изменение разделителей столбцов в файле

Проблема состоит в том, что обратные галочки расширены слишком рано (т.е. не однажды для каждого аргумента, отправленного в xargs). Мог бы быть лучший путь, но необходимо смочь сойти с рук явный цикл удара:

grep -R 'mystring' . | cut -d: -f 1 | uniq | while read f; do touch "/tmp/`basename $f`"; done
6
21.08.2013, 01:21
3 ответа
tr ' ' '\t' < file 1<> file

Заменил бы каждый пробел символом табуляции.


Только для ответа на людей, говорящих, это не безопасно:

Оболочка откроет файл для чтения на дескрипторе файла 0, и для чтения-и-записи на дескрипторе файла 1. Если какой-либо из тех перестанет работать, то это прыгнет с парашютом, tr не будет даже выполняться. Если перенаправления успешны, tr выполняется.

tr считает файл один блок за один раз, сделает транслитерацию и произведет измененный блок по неизмененному.

При этом это не должно будет обычно выделять место на диске. Исключение к этому было бы то, если бы файл был редкими для начала, или файловыми системами та копия на записи реализации. Таким образом, ошибки для "никакого пространства, доступного", маловероятны.

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

В любом случае, на отказ write() системный вызов, tr должны сообщить ошибка и выход. Поскольку его stdout открыт в режиме чтения-записи, это не будет усеченным. Чтобы файл был усеченным, tr должен был бы явно звонить truncate() на его стандартном выводе на выходе, который не имел бы смысла.

Что произошло бы, хотя будет то, что файл частично транслитерировался бы (до такой степени, когда tr отказавший).

Что я узнал, хотя то, что GNU tr в настоящее время находимый на Debian sid amd64 имеет ошибку в этом это segfaults на отказ write() системный вызов и выходной мусор на stdout (редактирование, теперь зафиксированное начиная с версии 2.19-1 пакета libc6 Debian). Это на самом деле повредило бы файл (но снова не усекло бы его).

tr ' ' '\t' < file > newfile && mv newfile file

не заменил бы file если newfile был правильно создан, но имеет много проблем, связанных с ним:

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

tr ' ' '\t' < file 1<> file более безопасно, чем наиболее часто используемое perl -pi -e 's/ /\t/g' потому что на отказ perl (как на полном диске), Вы теряете исходный файл и только добираетесь что perl сумел произвести до сих пор.

8
27.01.2020, 20:23
  • 1
    Это работает - я должен допустить меня даже не новый это tr существовавший. Но так или иначе Спасибо! –  sdf 20.08.2013, 17:10

Можно использовать sed также.

sed -i.bak 's/ /\t/g' filename

Это создаст a filename.bak прежде, чем отредактировать файл.

s/ /\t/g => Это говорит sed заменять пространством с символом табуляции глобально через каждую строку файла.

2
27.01.2020, 20:23

Для изменения каждого пространства в файле к вкладке использовать tr.

tr ' ' '\t' <input_file >output_file

Для изменения каждой последовательности одного или нескольких располагают с интервалами к единственной вкладке, используют sed.

sed -e 's/  */\t/g' <input_file >output_file

Некоторые sed реализации понимают \t для значения вкладки другим нужен литеральный символ табуляции.

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

1
27.01.2020, 20:23

Теги

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