我正在尝试从文本文件中删除前 N 个字符,重要的是 它不是逐行完成的。
目前,我编写的这段代码从每行中删除了"i"个字符数。但我想从全文中删除。
for FILE in *;
do x=$(wc -c < "$FILE"); for ((i=1; i <= $x; ++i));
do sed "s/^.{$i}//" $FILE > $i;
done;
done;
例如,我在目录 xml/root 中有这个 xml 文件.xml
<ticket id="usa-001" REFUND="NO" TEST="TEST">
<airline>Us Airlines</airline>
<emptytag id="usa-001" REFUND="NO" TEST="TEST"/>
<preis>30</preis><seat>
<allseats>120</allseats>
</ticket>
我想要的是删除前 N 个字符并将其保存到新文件中。 假设 5 所以它会是
et id="usa-001" REFUND="NO" TEST="TEST">
<airline>Us Airlines</airline>
<emptytag id="usa-001" REFUND="NO" TEST="TEST"/>
<preis>30</preis><seat>
<allseats>120</allseats>
</ticket>
如果您真的只想过滤掉文件的前 n 个字符,您需要的工具是dd
它允许您指定要跳过的块数。 如果希望块大小为 1,请使用bs
指定。 例如,要跳过输入文件的前 2 个字符,请使用:
$ echo foobarbaz | dd bs=1 skip=2 2> /dev/null
obarbaz
您可以使用if
指定输入文件,但重定向可能更简单。dd
向 stderr 写入一堆诊断信息,输出重定向只是为了抑制这些消息。 由于块大小很小,这将像污垢一样慢,但是(如果您有支持此功能的 dd)您可以比sed
快得多:
dd iflag=skip_bytes skip=5
使用 GNU sed:
$ sed -Ez 's/^.{5}//' root.xml > 5
$ cat 5
et id="usa-001" REFUND="NO" TEST="TEST">
<airline>Us Airlines</airline>
<emptytag id="usa-001" REFUND="NO" TEST="TEST"/>
<preis>30</preis><seat>
<allseats>120</allseats>
</ticket>
如果要在少于 5 个字符的文件中删除最多 5 个字符,请使用{1,5}
而不是{5}
。
你也可以使用tail
:
# display from 4th byte
# in other words, remove first 3 bytes
$ printf 'applenbanananfigncherryn' | tail -c +4
le
banana
fig
cherry
使用您显示的示例,请尝试以下awk
代码。用 GNUawk
编写和测试。
对于单Input_file:
awk -i inplace -v RS='^.{5}' -v ORS='' 'END{print}' Input_file
对于具有GNUawk
的多个Input_file:在此处使用ENDFILE
函数,该函数将按照名称处理每个Input_file末尾的所有行。
awk -i inplace -v RS='^.{5}' -v ORS='' 'ENDFILE{print}' *
withcut
n=5; cut -c$n- file.txt
看起来您想将每一行保存在文件中。
n=5; cut -c$n- file.txt | awk '{print $0 > NR}'
<小时 />n=5; cut -c$n- file.txt | awk '{print $0 > NR; exit}'
你知道,你也可以使用hexdump
:
hexdump -s 5 -ve '/1 "%c"' inputfile > outfile
你可以做一些像这样丑陋和丑陋的事情——
awk 'BEGIN{ left=100 } { if (left>0) { len=length($0); if (len<left) { left-=len+1; next } else { print substr($0,left); len=0; next } } else print $0 }' infile
不要,拜托...请改用 Ed 的sed
。
您可以使用Perl
-
perl -e 'seek(STDIN,100,0) && print <>' < infile # simpler
perl -e '$/=undef; open(my $fh,$ARGV[0]); seek($fh,100,0) && print <$fh>' infile # cleaner
但是威廉的dd
在不需要任何代码的情况下处理二进制文件......
dd bs=1 skip=100 < infile > outfile
如果您的版本理解+
选项,Sundeep 的可能是文本文件最合适的目标-
tail -c +101 infile # start at byte 101, having skipped the first 100
如果你知道它是ASCII
:
jot -s '' 27 | gsed -zE 's/.{15}/&n/g; s/[n]+$/n/g'
123456789101112
131415161718192
021222324252627
mawk 5 RS='^.....' ORS=
6789101112
131415161718192
021222324252627
假设它符合文本UTF-8
那么这应该可以预先清理多达 5 个任何类型的 unicode 字符,包括换行符:
printf '%s' "${test_input}" | gnu-wc -lcm
ꜜ&$Ꝡ*&.(ꢔ2*ꥴ6,꩸:.ꮘ>0곌B2긌F4꽐J6낐N8뇄R:다V<돨Z>듈^@땼bB뗼fD뙀jF
0 54 90
mawk2 'BEGIN { FS = "^" (_=(_="([\000-\177]|" "[\302-\364][\200-\277]+)")(_=(_)_)_ OFS = ORS =__="" _+=_^= RS = "^$" } __!= $(NF *=_==NF )' | gnu-wc -lcm
0 49 81