格式化xargs输出


10

我想更改输出xargs显示的格式

cat k.txt 
1 
2 
3 

cat k.txt | xargs 
1 2 3

但是我想有1, 2, 31|2|3。有什么建议?


这可能与一些来实现(不完全这样)像xargs cat -n,但更容易,如果你只是修剪换行符,这可以实现echo $(cat)grep或者awk(爬行做到这一点的方式)。xargs不太适合您当前的目的。
41754 2013年

Answers:


18

以下是十几个有关如何获取此类文件的示例:

$ cat k.txt
1
2
3

并将其转换为以下格式:

1,2,3

如果您想一起玩,可以使用此命令来创建上述文件:

$ cat <<EOF > k.txt
1
2
3
EOF

以下示例分为两组。“工作”的人和“几乎”工作的人。我离开这些是因为,通常,查看为什么某事无效与查看为什么某事有用同等重要。

我所熟悉的大多数脚本语言都可以使用。其中一些被多次表示,因为就像Perl中通常引用的著名首字母缩写TIMTOWTDI一样

注意:您可以,在下面的示例中换出逗号(),然后将其替换为所需的任何字符,即|

“工作”的例子

这些代码片段将产生所需的输出。

paste命令:

$ paste -s -d ',' k.txt 
1,2,3

sed命令:

$ sed ':a;N;$!ba;s/\n/,/g' k.txt
1,2,3

$ sed ':a;{N;s/\n/,/};ba' k.txt 
1,2,3

perl命令:

$ perl -00 -p -e 's/\n(?!$)/,/g' k.txt
1,2,3

$ perl -00 -p -e 'chomp;tr/\n/,/' k.txt
1,2,3

awk命令:

$ awk '{printf"%s%s",c,$0;c=","}' k.txt
1,2,3

$ awk '{printf "%s,",$0}' k.txt | awk '{sub(/\,$/,"");print}'
1,2,3

$ awk -vORS=, 1 k.txt | awk '{sub(/\,$/,"");print}'
1,2,3

$ awk 'BEGIN {RS="dn"}{gsub("\n",",");print $0}' k.txt | awk '{sub(/\,$/,"");print}'
1,2,3

python命令:

$ python -c "import sys; print sys.stdin.read().replace('\n', ',')[0:-1]" <k.txt
1,2,3

$ python -c "import sys; print sys.stdin.read().replace('\n', ',').rstrip(',')" <k.txt
1,2,3

Bash的mapfile内置功能:

$ mapfile -t a < k.txt; (IFS=','; echo "${a[*]}")
1,2,3

ruby命令:

$ ruby -00 -pe 'gsub /\n/,",";chop' < k.txt
1,2,3

$ ruby -00 -pe '$_.chomp!"\n";$_.tr!"\n",","' k.txt
1,2,3

php命令:

$ php -r 'echo strtr(chop(file_get_contents($argv[1])),"\n",",");' k.txt
1,2,3

注意事项

上面的大多数示例都可以正常工作。有些有隐藏的问题,例如上面的PHP示例。该函数chop()实际上是的别名rtrim(),因此最后一行的尾随空格也将被删除。

第一个Ruby示例和第一个Python示例也是如此。问题在于他们如何利用某种本质上盲目“截断”尾随字符的操作。在提供OP的示例中这很好,但是在使用这些类型的一种衬管时必须小心,以确保它们与所处理的数据相符。

说我们的示例文件,k.txt看起来像这样:

$ echo -en "1\n2\n3" > k.txt

看起来相似,但有一点点区别。它没有\n原始文件末尾的换行符()。现在,当我们运行第一个Python示例时,我们得到以下信息:

$ python -c "import sys; print sys.stdin.read().replace('\n', ',')[0:-1]" <k.txt
1,2,

“几乎”有效的示例

这些就是“永远是伴娘,永远不是新娘”的例子。他们中的大多数人可能都可以适应,但是当为问题寻求潜在的解决方案时,当感觉到“被迫”时,这可能是错误的工作工具!

perl命令:

$ perl -p -e 's/\n/,/' k.txt
1,2,3,

tr命令:

$ tr '\n' ','  < k.txt 
1,2,3,

cat+ echo命令:

$ echo $(cat k.txt)
1 2 3

ruby命令:

$ ruby -pe '$_["\n"]=","' k.txt
1,2,3,

Bash的while+ read内置函数:

$ while read line; do echo -n "$line,"; done < k.txt
1,2,3,

1
关于awk我更喜欢一个简短的选择:awk -vORS=, 1 k.txt
manatwork

不确定CentOS是否具有bashmapfile -t a < k.txt; (IFS=','; echo "${a[*]}")
manatwork

不确定尾随换行符。根据我的测试,您perl也首先awk拥有它们。
manatwork 2013年

我会把那个paste放在顶部。这paste -s就是这里的目的。这是一个标准命令,将是最有效的。所有其他的都过度使用和/或不便于携带或有限制。
斯特凡Chazelas

mapfile是相对较新的,在bash4.0中添加。
manatwork 2013年

4

@slm已经给出了很好的答案,但是作为您的问题“ xargs的格式输出”

xargs -I{} echo -n "{}|" < test.txt
  • -I 是“替换字符串”选项。
  • {} 是输出文本的占位符。
  • 这类似于在“查找”中使用花括号对。

如果您想摆脱尾随|,可以使用sed一些清理方法:

$ xargs -I{} echo -n "{}|" < k.txt  | sed -e 's/|$//'
1|2|3

这将在3.“ 1 | 2 | 3 |”之后添加一条额外的管道。我在while循环和awk解决方案中遇到了同样的问题。
slm

是的,如果有新的生产线.. trsed等也..
拉胡尔·帕蒂尔

2

我知道这是一个旧线程。OP用这样的简单代码询问。为了使其与原始版本保持接近,我有一个简单的解决方案。

cat k.txt | xargs
1 2 3

使用sed

cat k.txt | xargs | sed 's/ /,/g'
1,2,3

要么

cat k.txt | xargs | sed 's/ /|/g'
1|2|3

sed看起来有些怪异但已分解,这很有意义。

可以代替。g'是global的:没有这个,它将只对每条新行进行第一个替换。由于您使用“ xargs”,因此将它们显示为一行。这样您将得到“ 1,2 3”。

定界符用于分隔。我使用了/字符。一个有趣的技巧:只要我们在引号之间保持相同的格式,就可以用其他大多数字符替换定界符。所以这也可以工作...

cat k.txt | xargs | sed 's# #,#g'

要么

cat k.txt | xargs | sed 'sT T,Tg'

显然,使用某些字符作为定界符可能会造成混淆,因此要聪明。


0
xargs <k.txt | tr \  \|

您不需要cat-只需传递文件输入,并且-如果没有其他命令- xargs将传递其默认格式-这种格式带有/bin/echo(不带反斜杠c-escape解释)

xargs将从输入文件中删除头/尾空格,并将其他空白序列压缩到单个空格。这意味着在将文件从传递tr至时xargs

tr \\n \| <k.txt | xargs

...印刷品...

1|2|3|

... 以另一种方式,并且仅在空间定界的argsxargs操作...。

1|2|3\n

...因为会xargs打印最后的尾随换行符(这是文本文件所必需的),但是不会以tr这种方式解析出来。

但是请注意,此方法(或此处提供的任何其他解决方案)并未考虑xargs输入中的引用。xargs会在输入中传递字面上用单引号/双引号/反斜杠引起来的非换行符,它们本身可以像这样被引用:

xargs <<\IN
1    2'      3'\'      \'4
IN

1 2      3' '4
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.