考虑这个文件
$ cat infile.txt
1111
2222
3333
4444
请注意,每行至少有2个前导空格。我想要 将所有线均匀地移动,直到至少一条线没有前导空格, 示例
$ cat outfile.txt
1111
2222
3333
4444
现在在这种情况下,这意味着将一切都留下2个空格,但是 解决方案需要使用可能需要更多或更少的其他文件 移动。如果可能,请使用awk或sed执行此任务。我试过这个
awk '(sub(" ",""))' infile.txt
但是如果一条线最初的空间少于2个,它将不起作用。
答案 0 :(得分:2)
这可能适合你(GNU sed):
sed -r 'H;$!d;x;:a;/\n+\S/!s/(\n+) /\1/g;ta;s/.//' file
感谢NeronLeVelu,我只是整理了他的解决方案。
答案 1 :(得分:1)
这是awk
awk -F"[^ ]" '!NF {next} {s=length($1);a[NR]=$0} min>s||NR==1 {min=s} END {for (i=1;i<=NR;i++) print substr(a[i],min+1)}' file
1111
2222
3333
4444
它会计算第一个字符前面的空格,然后找到最小的数字 使用它,然后在文本前面删除空格。
更具可读性:
awk -F"[^ ]" '
!NF {next}
{s=length($1)
a[NR]=$0}
min>s||NR==1 {
min=s}
END {
for (i=1;i<=NR;i++)
print substr(a[i],min+1)}
' file
通过将字段分隔符设置为"[^ ]"
(不是空格),第一个字段将包含空格组
这种方式length($1)
给出了文本前面的空格数,无论文本中是否有更多空格。
答案 2 :(得分:1)
sed '#n
H;${x
:cycle
h
:nld
s/\(\n\)\1/\1 \1/g;t nld
s/\(n\)$/\1 /
/\n[^ ]/ !{
s/\(\n\)[ ]/\1/g
b cycle
}
x
s/.//p
}' YourFile
³
(用作分隔符,但可以使用其他字符)。感谢@potong关于不同错误的所有有用的评论或简单的algorythm
答案 3 :(得分:1)
另一个(G)awk
两次读取文件(内存不足)
awk '{a=(x=match($0,/[^ ]/))<a||!a?x:a}FNR!=NR{print substr($0,a)}' file{,}
检查第一个空格是否存储并存储。
然后在第二个文件上打印从存储的最低值开始的行的子行。
一次读取文件(使用大量内存)
awk '{a=(x=match(b[NR]=$0,/[^ ]/))<a||!a?x:a}END{while(++i<=NR)print substr(b[i],a)}' file
与第一行相同,除了每行存储在一个数组中,并且打印数组中每行的子字符串。
input
1111 1111
2222 2222
3333 3333
4444 4444
output
1111 1111
2222 2222
3333 3333
4444 4444
答案 4 :(得分:0)
使用perl:
脚本中的:
#!/usr/bin/env perl
use strict; use warnings;
my $len;
while (<>) {
if ($. == 1) {
(my $spaces = $_ ) =~ s/^(\s+).*/$1/;
$len = (length $spaces) - 1;
}
print substr $_, $len;
}
或在命令行中:
$ perl -ne '
$. == 1 and do{
(my $spaces = $_ ) =~ s/^(\s+).*/$1/;
$len = (length $spaces) - 1;
};
print substr $_, $len
' file
答案 5 :(得分:0)
我知道您需要左移 2个空格的倍数。
我尝试使用sed和shell尽可能简短和简单:
#while there is no line beginning with 0 spaces
while ! grep "^ \?[^ ]" infile.txt > /dev/null; do
#on each line of the file remove the first spaces
sed -i "s/^ //" infile.txt ;
done
注1: grep指令与空行不匹配。因此,空行不被视为未移位的行。
您可能希望grep匹配空行:“^ \?[^] \ | ^ $”
注2: 空文件,会使循环无限。 你可能想要使用grep -v“^”,在这种情况下:空行被认为没有移位。
请注意,您可以创建infile.txt的副本,而不是使用它。
我确信可以将while循环和grep转换成一些sed指令。但是你必须连接sed缓冲区中的所有行,这不是它的名义用途。
答案 6 :(得分:0)
一种方法,使用AWK:
awk 'FNR==NR {
x = length($0)
sub(/^ */, "")
y = x - length($0)
if (r > y || NR==1) r = y
next
}{
print substr($0, r + 1)
}' infile.txt{,}
此解决方案两次读取输入文件: