Как удалить символ новой строки в конце файла?

Получив ответ Стивена Китта и обсудив эту команду как потенциальное решение:

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

Я решил не запускать ее, пока не пойму, что происходит, этот ответ описывает то, что я узнал и что в итоге сделал.

Я использую Gnu mv , который копирует файлы в целевой объект, и только если операция копирования прошла успешно, он удаляет оригинал.
Однако я хотел проверить, выполняет ли mv эту последовательность по одному файлу за раз, если бы это было правдой, исходное содержимое папки было бы чисто разрезано на две части, одна часть переместился к месту назначения, другой остался у источника. И, возможно, был бы один файл, который был прерван во время копирования, который будет общим для двух каталогов - и он, вероятно, будет иметь неправильный формат.

Чтобы обнаружить файлы, которые были общими в двух каталогах, я выполнил:

~% sudo diff -r --report-identical-files my_data_on_60GB_partition/. /media/admin/mydata/. | grep identical | wc -l
14237

Этот результат предполагает наличие 14 237 экземпляров одних и тех же файлов как в исходном, так и в целевом каталогах, что я подтвердил, проверив файлы вручную - да, были много одинаковых файлов в обоих каталогах. Это говорит о том, что только после того, как mv скопирует большие объемы файлов, он выполнит удаление исходных файлов. Быстрый поиск в info в команде mv показал

Он [ mv ] сначала использует часть того же кода, который используется cp -a для копирования запрошенных каталогов и файлов, затем (при условии, что копирование выполнено успешно) удаляет оригиналы. Если копирование не удается, то часть , которая была скопирована в целевой раздел, удаляется.

Я не запускал команду, но подозреваю, что если бы я попытался запустить

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

Приглашение -i перед перезаписью , вероятно, сработало бы более 14 000 раз.

Итак, чтобы узнать, сколько всего файлов во вновь созданном каталоге:

~% sudo find my_data_on_60GB_partition/ -type f -a -print | wc -l                                                                    
14238

Итак, если в новом каталоге было всего 14238 обычных файлов и 14237 имели идентичные оригиналы в исходном каталоге, это означает, что только один файл в новом каталоге, у которого не было соответствующего идентичного файла в источнике. Чтобы узнать, что это за файл, я запустил rsync обратно в направлении источника:

~% sudo rsync -av --dry-run my_data_on_60GB_partition/ /media/admin/my_data
sending incremental file list
./
Education_learning_reference/
Education_learning_reference/Business_Education/
Education_learning_reference/Business_Education/Business_education_media_files/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/018 business plans-identifying main KPIs.flv

sent 494,548 bytes  received 1,881 bytes  330,952.67 bytes/sec
total size is 1,900,548,824  speedup is 3,828.44 (DRY RUN)

Быстрая проверка подтвердила, что это был искаженный файл, где файл существовал как в источнике, так и в месте назначения, целевой файл = 64 МБ, оригинал = 100 МБ.Этот файл и его иерархия каталогов все еще принадлежали пользователю root, и исходные разрешения еще не были восстановлены.

Итак, вкратце:

  • все файлы, которые mv так и не достигли, все еще вернулись на свои исходные места (очевидно)
  • все файлы, которые mv скопировали полностью в исходном каталоге все еще были их оригинальные копии
  • файл, который был скопирован лишь частично, все еще имел оригинал обратно в исходный каталог

Другими словами, все исходные файлы были по-прежнему нетронутыми, и решение в этом случае заключалось в том, чтобы просто удалите новый каталог!

37
12.01.2016, 13:36
2 ответа

Вы можете добиться этого с помощью Perl как:

perl -pi -e 'chomp if eof' myfile

По сравнению с truncateили ddэто не оставит вас с испорченным файлом, если myfileна самом деле не имеет завершающих строк новой строки.

(ответ построен из комментария и на основе этого ответа)

37
27.01.2020, 19:36
perl -0pi -e "s/\R\z//g" file

Работает для "\r" (MAC ), "\r\n" (Windows )и "\n" (Linux ). Для повторяющихся новых строк (любой тип )в конце файла вы можете сделать:

perl -0pi -e "s/\R*\z//g" file
2
31.01.2021, 14:12

Теги

Похожие вопросы