Передача файлов с разрывами строк в именах файлов на сервере Linux

(где ввод - это файл, содержащий текст для повторения)

С GNU awk (и при условии, что ввод не содержит байтов NUL):

awk -v n=100 -v RS='\0' -v ORS= '{while (n--) print}' < input

Переносимость :

awk -v n=100 -v ORS= '
  {all = all $0 RS}
  END {while (n--) print all}' < input

(обратите внимание, что если ввод не заканчивался символом новой строки, он будет добавлен).

Вы также можете делать такие вещи, как:

set --
n=100; while [ "$n" -gt 0 ]; do
  set -- "$@" input
  n=$((n - 1))
done
cat "$@"

Это будет работать независимо от того, какой байт содержит вход . Однако обратите внимание, что для больших значений n и если ваша оболочка не имеет встроенного cat , вы можете достичь системного ограничения на размер аргументов команды (здесь кот ).

С помощью zsh или последних версий bash или ksh93 или yash -o braceexpand для фиксированного текста вы можете делать что-то например:

printf '%.0sstring1\nstring2\nstring3\n' {1..100}

С zsh :

repeat 100 print -l string{1..3}

Если мы дерзки, в системах с установленным GNU seq мы также можем сделать:

seq -f 'string1
string2
string%.0g' 3.0001 0.0001 3.0100
3
22.07.2017, 22:44
2 ответа

Новая строка так же допустима, как и любой другой символ в имени файла в Unix. Для оболочки этот символ имеет особое значение (, он разделяет команды ), поэтому его необходимо заключать в кавычки, как и любые другие специальные символы (, такие как пробел, ;, |... ).

В Bourne -, как и в оболочках, это можно сделать с помощью одинарных или двойных кавычек:

ls -d 'a
b'

Или:

ls -d "a
b"

Некоторые оболочки (ksh93, zsh, bash, mksh, FreeBSD shкак минимум )также поддерживают:

ls -d $'a\nb'

Для scpобратите внимание, что имя файла передается в оболочку входа удаленного пользователя. Когда вы делаете:

scp file user@host:something

это приводит к вызову оболочки входа пользователя в hostдля интерпретации:

scp -t something

командная строка (по крайней мере с openssh ). Итак, если эта оболочка похожа на Борна -,это должно быть:

scp 'src/a
b' user@host:"dest/'a
b'"

Если да:

scp 'a
b' user@host:dest/

или

scp -r src user@host:dest/

sshd на сервере работает:

scp -t dest/

или

scp -r -t dest/

И имена файлов не передаются в командной строке удаленной оболочки, а встраиваются в поток данных между клиентом и сервером scp. Однако я обнаружил (с openssh 7.2p2 по крайней мере ), что символ новой строки в конечном итоге преобразуется в\^J(3 символа ).

Таким образом, вы можете использовать другой механизм вместо ssh, который обеспечивает более надежную передачу файлов, например rsync, sftp, или tar:

.
tar cf - src | gzip | ssh user@host 'cd dest && gunzip | tar xpf -'

Это также позволит лучше сохранять жесткие ссылки, программные ссылки и другие атрибуты файлов. Вам также может понадобиться рассмотреть преобразование кодировки, если имена файлов содержат символы, отличные от -ASCII.

4
27.01.2020, 21:18

Чтобы переименовать существующие файлы, которые имеют символы новой строки (, предполагая, что они )в них, с ksh93, zsh, bashилиmksh:

for f in *$'\n'*; do mv -i -- "$f" "${f//$'\n'/}"; done

Шаблон глобуса *$'\n'*говорит, что нужно сопоставлять любые/все имена файлов, в которых есть символы новой строки; команда mvпереименовывает файлы, удаляя из них все экземпляры новой строки.

1
27.01.2020, 21:18

Теги

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