Я работаю в своем терминале с помощью bash, пытающегося переименовать папки:
1
2
3
4
5
Я хотел бы переименовать их в соответствии с файлом a.txt:
a 2
c 3
d 5
e 1
b 4
Порядок в файле .txt полностью случайный. Я надеюсь найти способ, которым я могу переименовать папку, чтобы они стали:
1 > e
2 > a
3 > c
4 > b
5 > d
Есть ли способ сделать это?
Спасибо большое! [!d4 ]
Вы можете использовать xargs с mv:
xargs -r -a /path/to/file.txt -L1 mv
(если вы находитесь в каталоге, где находятся файлы).
xargs преобразует введите аргументы для команды.
-a foo, чтобы прочитать ввод из foo. -L1 использовать ровно одну строку ввода для каждого вызова команды. -r, чтобы избежать запуска команды, если строка пустаНапример, используя echo mv вместо mv, чтобы показать выполняемые команды:
$ xargs -r -a foo.txt -L1 echo mv
mv a 2
mv c 3
mv d 5
mv e 1
mv b 4
Вы также может использовать опцию -p для подтверждения xargs перед запуском команды:
$ xargs -r -p -a foo.txt -L1 mv
mv a 2 ?...n
mv c 3 ?...n
mv d 5 ?...y
mv e 1 ?...mv: cannot stat ‘d’: No such file or directory
n
mv b 4 ?...
В файле a.txt есть одна запись в строке, поэтому перечисленные имена не содержат символ \n (новая строка), справа?
Строка содержит 2 имени, разделенных пробелом char, поэтому имена не содержат пробела, не так ли? (или другая возможность - использовать фиксированную длину для перечисленных имен).
Попробуйте это, если имена не содержат ни символов \n, ни space:
[ f1]awk используется для изменения порядка имен в строках, считанных из файла a.txt. \0 используется для разделения имен при печати на стандартный вывод.
xargs читает стандартный ввод:
-0: \0 используется как разделитель для элементов, считанных со стандартного ввода -L 2 mv: команда mv вызывается с двумя параметрами за раз.Тест:
$ ls -al
total 40
drwxrwxr-x 7 stacko stacko 4096 May 31 11:25 .
drwxrwxr-x 21 stacko stacko 12288 May 31 11:23 ..
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 1
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 2
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 3
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 4
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 5
-rw-rw-r-- 1 stacko stacko 20 May 31 11:24 a.txt
$ cat a.txt
a 2
c 3
d 5
e 1
b 4
$ awk '{printf("%s\0%s\0",$2,$1)}' a.txt | xargs -0 -L 2 mv -v
'2' -> 'a'
'3' -> 'c'
'5' -> 'd'
'1' -> 'e'
'4' -> 'b'
$ ls -al
total 40
drwxrwxr-x 7 stacko stacko 4096 May 31 11:26 .
drwxrwxr-x 21 stacko stacko 12288 May 31 11:23 ..
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 a
-rw-rw-r-- 1 stacko stacko 20 May 31 11:24 a.txt
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 b
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 c
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 d
drwxrwxr-x 2 stacko stacko 4096 May 31 11:25 e
В простом случае, который вы показываете выше, где каждая строка имеет два слова, целевую директорию и новое имя и где ни одно из них не может содержать пробелов, вы можете просто сделать:
while read -r from to; do mv "$from" "$to"; done < file
[d1 ] Это будет читать каждую строку в file, назначая первую строку (до первого пробела) до $from, а остальную часть строки - $to, а затем запустите mv для каждого из них.