如何将多行文件名连接到一个自定义分隔符?

时间:2010-05-04 09:09:40

标签: linux bash shell parsing merge

我想将ls -1的结果加入到一行中,并用我想要的任何内容划分它。

我可以使用任何标准Linux命令来实现此目的吗?

22 个答案:

答案 0 :(得分:567)

与第一个选项类似,但省略了尾随分隔符

ls -1 | paste -sd "," -

答案 1 :(得分:345)

  

编辑:只需“ ls -m ”如果您希望分隔符为逗号

啊,力量和简洁!

ls -1 | tr '\n' ','

将逗号“”更改为您想要的任何内容。请注意,这包括“尾随逗号”

答案 2 :(得分:22)

这会用换行符替换最后一个逗号:

ls -1 | tr '\n' ',' | sed 's/,$/\n/'

ls -m包括屏幕宽度字符的换行符(例如80)。

主要是Bash(只有ls是外部的):

saveIFS=$IFS; IFS=$'\n'
files=($(ls -1))
IFS=,
list=${files[*]}
IFS=$saveIFS

在Bash 4中使用readarray(又名mapfile):

readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS

感谢gniourf_gniourf的建议。

答案 3 :(得分:19)

我认为这个很棒

ls -1 | awk 'ORS=","'

ORS是“输出记录分隔符”,因此现在您的行将以逗号连接。

答案 4 :(得分:14)

设置IFS和使用"$*"的组合可以达到您想要的效果。我正在使用子shell,所以我不会干扰这个shell的$ IFS

(set -- *; IFS=,; echo "$*")

要捕获输出,

output=$(set -- *; IFS=,; echo "$*")

答案 5 :(得分:12)

一般解析be_in_bbox(min_long, max_long, min_lat, max_lat) is not advised,所以另一种更好的方法是使用ls,例如:

find

或者使用find . -type f -print0 | tr '\0' ',' find

paste

对于一般连接多行(与文件系统无关),请检查:Concise and portable “join” on the Unix command-line

答案 6 :(得分:9)

不要重新发明轮子。

ls -m

确实如此。

答案 7 :(得分:7)

只是bash

mystring=$(printf "%s|" *)
echo ${mystring%|}

答案 8 :(得分:7)

此命令适用于PERL粉丝:

ls -1 | perl -l40pe0

这里40是空格的八进制ascii代码。

-p将逐行处理并打印

-l将负责用我们提供的ascii字符替换尾部\ n。

-e是告知PERL我们正在执行命令行。

0表示实际上没有命令可以执行。

perl -e0与perl -e''

相同

答案 9 :(得分:6)

为了避免tr的潜在新行混淆,我们可以将-b标志添加到ls:

ls -1b | tr '\n' ';'

答案 10 :(得分:4)

看起来答案已经存在。

如果你想 a, b, c格式,使用ls -mTulains Córdova’s answer

或者,如果您想要a b c格式,请使用ls | xargs(简化版Chris J’s answer

或者,如果您想要|之类的任何其他分隔符,请使用ls | paste -sd'|'Artem’s answer的应用程序)

答案 11 :(得分:3)

如果你的xargs版本支持-d标志,那么这应该可以工作

ls  | xargs -d, -L 1 echo

-d是分隔符标志

如果您没有-d,则可以尝试以下

ls | xargs -I {} echo {}, | xargs echo

第一个xargs允许您指定分隔符,在此示例中为逗号。

答案 12 :(得分:3)

sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]

说明:

-e - 表示要执行的命令
   :a - 是标签
   /$/N - 定义当前和(N)分支线的匹配范围
   s/\n/\\n/; - 用\n替换所有EOL    ta; - 如果匹配成功,请转到标签a

取自my blog

答案 13 :(得分:3)

sed方式,

sed -e ':a; N; $!ba; s/\n/,/g'
  # :a         # label called 'a'
  # N          # append next line into Pattern Space (see info sed)
  # $!ba       # if it's the last line ($) do not (!) jump to (b) label :a (a) - break loop
  # s/\n/,/g   # any substitution you want

注意

这是复杂的线性,在所有行都附加到sed的模式空间后只替换一次。

@AnandRajaseka的answer以及其他一些类似的答案,例如here,是O(n²),因为每次将新行附加到模式空间时,sed必须替换。< / p>

比较,

seq 1 100000 | sed ':a; N; $!ba; s/\n/,/g' | head -c 80
  # linear, in less than 0.1s
seq 1 100000 | sed ':a; /$/N; s/\n/,/; ta' | head -c 80
  # quadratic, hung

答案 14 :(得分:2)

ls在连接到管道时产生一个列输出,因此-1是多余的。

这是使用内置join函数的另一个perl答案,该函数不会留下尾随分隔符:

ls | perl -F'\n' -0777 -anE 'say join ",", @F'

晦涩的-0777使perl在运行程序之前读取所有输入。

选择不留下尾随分隔符的替代

ls | sed '$!s/$/,/' | tr -d '\n'

答案 15 :(得分:2)

您可以使用:

ls -1 | perl -pe 's/\n$/some_delimiter/'

答案 16 :(得分:1)

除了majkinetor的回答之外,这里是删除尾随分隔符的方法(因为我不能只根据他的回答评论):

ls -1 | awk 'ORS=","' | head -c -1

只需删除与分隔符一样多的尾随字节。

我喜欢这种方法,因为我可以使用多字符分隔符+ awk的其他好处:

ls -1 | awk 'ORS=", "' | head -c -2

修改

正如彼得所注意到的那样,本机MacOS版本的头部不支持负字节数。然而,这很容易解决。

首先,安装coreutils。 &#34; GNU Core Utilities是GNU操作系统的基本文件,shell和文本操作实用程序。&#34;

brew install coreutils

MacOS提供的命令也安装了前缀&#34; g&#34;。例如gls

完成此操作后,您可以使用具有负字节数或更好字节数的ghead来制作别名:

alias head="ghead"

答案 17 :(得分:1)

如果Python3是您的最佳选择,您可以这样做(但是请解释为什么会这样):

ls -1 | python -c "import sys; print(','.join(sys.stdin.read().splitlines()))"

答案 18 :(得分:0)

ls-m选项,可以用", "逗号和空格分隔输出。

ls -m | tr -d ' ' | tr ',' ';'

将此结果传递给tr以删除空格或逗号将允许您再次将结果传递给tr以替换分隔符。

在我的示例中,我使用分隔符,替换分隔符;

用您喜欢的一个字符分隔符替换;,因为tr只会考虑您作为参数传入的字符串中的第一个字符。

答案 19 :(得分:0)

您可以使用chomp在一行中合并多行:

perl -e&#39; while(&lt;&gt;){if(/ \ $ /){chomp; } print;}&#39; bad0&gt;测试

在if语句中放入换行符条件。它可以是特殊字符或任何分隔符。

答案 20 :(得分:0)

带有尾部斜杠处理的快速Perl版本:

ls -1 | perl -E 'say join ", ", map {chomp; $_} <>'

说明:

  • perl -E:以功能支持(例如,...)执行Perl
  • 说:打印带有承运人退货
  • 加入“,”,ARRAY_HERE:使用“,”
  • 加入数组
  • 地图{chomp; $ _}行:从每一行中删除载体返回并返回结果
  • <>:stdin,每行都是一个ROW,再加上一个映射,它将创建每个ROW的数组

答案 21 :(得分:0)

上面的Python答案很有趣,但是自己的语言甚至可以使输出更好:

ls -1 | python -c“ import sys; print(sys.stdin.read()。splitlines())”