Это только работает потому что tr
не изменяет размер файла.
1<>file
открывается file
как стандартный вывод в режиме перезаписи. (<>
назван режимом чтения-записи, но начиная с небольшого количества чтения программ stdout
, более полезно сфокусироваться на том, что это на самом деле делает.)
Обычно, когда Вы перенаправляете вывод (>file
), файл открыт в режиме "записи", который заставляет его или быть созданным или освобожденным. Другая общая опция >>file
, "добавьте" режим, который пропускает шаг, где файл освобожден, но помещает весь вывод в конец. 1<>file
также пропуски, освобождающие файл, но это помещает курсор записи в начале файла. (Вам нужно 1
потому что <>
значения по умолчанию к перенаправлению stdin
, нет stdout
).
Это только достаточно редко полезно, так как очень немного утилит так точны в своей модификации. Другой случай был бы поиском и заменой, где замена является точно той же длиной как оригинал. (Более короткая замена не работала бы также, потому что файл не является усеченным в конце; если бы вывод короче, чем оригинал, Вы закончили бы с любым используемым, чтобы быть в конце файла, все еще являющегося в конце файла.)
Вы можете использовать awk для разделения Первый столбец:
~$ awk '{split($1,a,";"); $1="";for (i in a){print a[i],$0}}' myfile
K00001 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00004 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00008 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
Вы разбили первый столбец на ;
; ( (
(
(
(
(
($ 1, A, «;»)
), а затем вы удаляете его, чтобы распечатать целое (новое ) Линия ( $ 0
) Для каждого элемента в массиве.
Как предложено в комментарии, после редактирования, мы видим, что вкладки используются в качестве сепаратора. Чтобы использовать вкладку в качестве сепаратора вывода полей, вы можете использовать ofS = «\ T»
, например, в начнется
часть awk. Кроме того, пустое поле вставляется с $ 1 = ""
. Итак, вместо печати [I]
$ 0
, лучше установить $ 1
на A [I]
, а затем печать $ 0
:
~$ awk 'BEGIN{OFS="\t"}{split($1,a,";"); for (i in a){$1=a[i];print}}' myfile
K00001 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00004 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00008 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
Это должно делать то, что ты хочешь. В основном, мы помещаем первое поле (клавиши) в $k
, а остальные поля в $f
путем разбиения на \t
и ограничения разбиения на первые 2
поля. Затем мы разделим клавиши на ;
и распечатаем каждую клавишу вместе с оставшимися полями на своей строке.
perl -nle '($k, $f) = split "\t", $_, 2; print "$_\t$f" for split ";", $k'
-n
циклов по входу. Вы можете либо перевести свой файл на perl, либо передать имя входного файла в конце командной строки. -l
включает автоматическое управление окончанием строки.
Я думаю, вам не нужно переименовать файлы. Вы можете преобразовать имена файлов на лету (First Sed), сравните их с датой (AWK) и преобразовывать соответствующие имена файлов обратно (второй SED).
find parent/directory -maxdepth 1 -type d -name 'bkp_*' | \
sed 's#parent/directory/bkp_\(..\)\(..\)\(....\)#\3\2\1#' | \
awk -v date=$(date --date='3 months ago' +%Y%m%d) '$0<$date{print $0}' | \
sed 's#\(....\)\(..\)\(..\)#parent/directory/bkp_\3\2\1#' | \
xargs rm -r
Вы должны проверить это без деталей RM Xargs RM!
-121--139844-файл awk
{
split($1,A,";") ;
for ( a in A )
{
printf "%s",A[a] ;
for(i=2;i<=NF;i++) printf "\t%s",$i ;
printf "\n" ;
}
}
где разделен
(1, а 1, а, «;»)
, введенный в все подпугивающее значение $ 1 для (A в A в A )
Структура через значение printf «% s», A [A];
; Распечатайте первое значение для (i = 2; i <= nf; i ++) printf "\ T % s ", $ i;
Печать оставшегося значения в командной строке printf" \ N ";
Новая строка Еще один Perl-одинлайнер.
$ perl -pe 's/^([^;]+);([^;]+);(\S+)\s+(.*)/$1 $4\n$2 $4\n$3 $4/' file
K00001 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00004 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00008 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
Другой сед-один лайнер.
$ sed 's/^\([^;]\+\);\([^;]\+\);\([^ ]\+\) \+\(.*\)/\1 \4\n\2 \4\n\3 \4/' file
K00001 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00004 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00008 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
Дольше Perl версия, которая позволяет получить доступ к данным на ключ и дополнительный процесс, если требуется. Это также не использует захват от регулярных выражений.
#!/usr/bin/perl
use warnings;
use strict;
my %hash;
while ( my $line = <> ){
#splitting the line into two parts at the first TAB.
my ($keys, $value) = split (/\t/ , $line, 2);
#splits the set of keys at each semicolon
my @key = split /;/, $keys;
#@key is used in scalar context here to get the number of keys.
#this is used to determine how many values we need to put into the hash
@hash{@key} = ($value) x @key;
}
for my $key (keys %hash){
print "$hash{$key}\n";
}
Дальнейшее чтение:
С sed
:
sed 's/^\([^[:blank:];]*\);\([^[:blank:]]*\)\(.*\)/\1\3\
\2\3/;P;D'
Медленный рабочий день, так что вот питон
решение
python3 -c 'import sys
x = (l.partition("\t") for l in sys.stdin)
x = ((l[0].split(";"), l[1] + l[2]) for l in x)
for a in x:
print(*a[0], sep=a[1], end=a[1])
' <file