Изменить несколько имен файлов unix - PullRequest
0 голосов
/ 17 марта 2020

Мне пришлось загрузить 15 ГБ данных, и по какой-то причине во время процесса загрузки имена файлов были перепутаны таким образом, что вместо

test_file.txt

имена файлов удваивались, поэтому это

test_file.txttest_file.txt

вместо. Моя единственная идея заключалась в том, есть ли способ подсчитать буквы, а затем переименовать каждый файл, удалив первую / или вторую половину имени файла? Имена файлов не совпадают, поэтому, например, в той же папке могут быть также файлы с именем

files_are_great.txtfiles_are_great.txt

, поэтому я изо всех сил пытаюсь найти способ l oop над ними.

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 17 марта 2020

Команда sed 's/\(.*\)\1/\1/' заменит все дублированные строки одной строкой, не требуя определенной части имени файла, такой как .txt. Он допускает пробелы в строке.

Пример:

echo 'abc defabc def' | sed 's/^\(.*\)\1$/\1/'

печатает

abc def

Объяснение команды sed:

  • ^ привязывает шаблон к началу строки
  • .* - это 0 или более вхождений любого символа
  • \( ... \) фиксирует то, что соответствует шаблону между
  • \1 - ссылка на первую группу захвата, т. е. текст, найденный до
  • $, привязывает шаблон поиска к концу строки

В результате шаблон поиска, который соответствует целой строке, состоящей из любого текста, за которым следует тот же текст.

  • \1 в замене - это та же ссылка на сопоставленный текст т. е. единственное вхождение дублированного текста.

Любые входные данные, которые не соответствуют шаблону, останутся без изменений.

Если вы хотите переименовать все файлы в текущем каталоге, вы можете используйте это следующим образом

for file in *
do
    new=$(echo $file|sed 's/\(.*\)\1/\1/')
    [ "$file" = "$new" ] || mv "$file" "$new"
done

В качестве команды sed d Если не изменить несоответствующий ввод, $new будет таким же, как $file для имен файлов, которые не состоят из дублированной строки. Это может привести к сообщению об ошибке от mv. Поэтому в этом случае переименование будет пропущено.

0 голосов
/ 17 марта 2020

Используя sed

sed 's#\(\.txt\)#& #g' 

Объяснение: используя \( \), мы группируем выражение, к которому можно получить доступ, используя &

Демо:

echo "files_are_great.txtfiles_are_great.txt" | sed 's#\(\.txt\)#& #g' 
files_are_great.txt files_are_great.txt 

Для переименование:

for file_name in $(ls -1 *txt*txt)
do 
new_file_name=$(echo $i |sed 's#\(\.txt\)#& #g'  | cut -d' ' -f1)
mv $file_name $new_file_name 
done 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...