提问人:JavaRocky 提问时间:5/4/2010 最后编辑:Mateen UlhaqJavaRocky 更新时间:2/20/2023 访问量:306570
如何使用自定义分隔符将多行文件名合并为一行
How to join multiple lines of filenames into one with custom delimiter
答:
如果您的 xargs 版本支持 -d 标志,那么这应该有效
ls | xargs -d, -L 1 echo
-d 是分隔符标志
如果您没有 -d,则可以尝试以下操作
ls | xargs -I {} echo {}, | xargs echo
第一个 xargs 允许您指定分隔符,在此示例中为逗号。
评论
-d
使用 GNU xargs 指定输入分隔符,因此不起作用。第二个示例与此处的其他解决方案存在相同的问题,即末尾的杂散分隔符。
编辑:只需“ls -m”,如果您希望分隔符是逗号
啊,强大而简单!
ls -1 | tr '\n' ','
将逗号“,”更改为您想要的任何内容。请注意,这包括一个“尾随逗号”(对于以换行符结尾的列表)
评论
\n
ls -1 | tr "\\n" "," | sed 's/\(.*\),/\1/'
sed
ls -1 | tr "\\n" "," | sed 's/,$//'; echo ''
sed
tr
ls -1 | tr '\n' ',' | head -c -1
您可以使用:
ls -1 | perl -pe 's/\n$/some_delimiter/'
评论
为了避免 tr 的潜在换行符混淆,我们可以在 ls 中添加 -b 标志:
ls -1b | tr '\n' ';'
这会将最后一个逗号替换为换行符:
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 中使用(aka ):readarray
mapfile
readarray -t files < <(ls -1)
saveIFS=$IFS
IFS=,
list=${files[*]}
IFS=$saveIFS
感谢gniourf_gniourf的建议。
评论
mapfile
mapfile -t files < <(ls -1)
IFS
IFS
saveIFS=$IFS; IFS=,; list=${files[*]}; IFS=$saveIFS
只是 bash
mystring=$(printf "%s|" *)
echo ${mystring%|}
评论
|
bash
printf
printf -v
|
printf -v mystring "%s|" * ; echo ${mystring%|}
设置和使用的结合可以做你想做的事。我正在使用一个子 shell,所以我不会干扰这个 shell 的$IFSIFS
"$*"
(set -- *; IFS=,; echo "$*")
要捕获输出,
output=$(set -- *; IFS=,; echo "$*")
评论
set
man set
set
--
set
--
help set
output=$( files=(*); IFS=,; echo "${files[*]}" )
type set
set is a shell builtin
man set
help set
set -- *
*
IFS=',' eval echo '"$*"'
paste -s -d
使用分隔符连接行(例如 ),并且不留下尾随分隔符:","
ls -1 | paste -sd "," -
评论
ls -1 | paste -s -d ":" -
paste
-
paste (GNU coreutils) 8.22
"\0"
paste -sd "\0" -
ls
当连接到管道时,会产生一个列输出,因此是冗余的。-1
这是另一个使用内置函数的 perl 答案,它不会留下尾随分隔符:join
ls | perl -F'\n' -0777 -anE 'say join ",", @F'
晦涩难懂使 perl 在运行程序之前读取所有输入。-0777
不留下尾随分隔符的 sed 替代方案
ls | sed '$!s/$/,/' | tr -d '\n'
我觉得这个太棒了
ls -1 | awk 'ORS=","'
ORS 是“输出记录分隔符”,因此现在您的行将用逗号连接。
评论
" OR "
)
此命令适用于 PERL 粉丝:
ls -1 | perl -l40pe0
这里 40 是空间的八进制 ascii 代码。
-p 将逐行处理并打印
-l 将负责将尾部 \n 替换为我们提供的 ASCII 字符。
-e 是通知 PERL 我们正在执行命令行。
0 表示实际上没有要执行的命令。
perl -e0 与 perl -e ' ' 相同
不要重新发明轮子。
ls -m
它正是这样做的。
评论
ls -m
tr
ls -m | tr -d ' '
sed 's/, /,/g
ls
可以选择用逗号和空格分隔输出。-m
", "
ls -m | tr -d ' ' | tr ',' ';'
通过管道将此结果用于删除空格或逗号,将允许您再次通过管道将结果用于替换分隔符。tr
tr
在我的示例中,我将分隔符替换为分隔符,
;
替换为您喜欢的任何一个字符分隔符,因为 tr 只考虑您作为参数传入的字符串中的第一个字符。;
sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]
解释:
-e
- 表示要执行
的命令 - 是一个标签 - 定义当前和 (N)ext 行
的匹配范围 - 将
所有 EOL 替换为 - 如果匹配成功,则转到标签
A:a
/$/N
s/\n/\\n/;
\n
ta;
摘自我的博客。
一般不建议解析,因此另一种更好的方法是使用 ,例如:ls
find
find . -type f -print0 | tr '\0' ','
或者通过使用 和 :find
paste
find . -type f | paste -d, -s
对于一般的多行连接(与文件系统无关),请查看:Unix 命令行上的简洁且可移植的“连接”。
评论
您可以使用 chomp 将多行合并为一行:
perl -e 'while (<>) { if (/\$/ ) { chomp; } print ;}' bad0 >测试
在 if 语句中放置换行符条件。它可以是特殊字符或任何分隔符。
看起来答案已经存在。
如果需要格式,请使用 ( Tulains Córdova 的回答a, b, c
ls -m
)
或者,如果您想要格式,请使用(Chris J 答案的简化版本a b c
ls | xargs
)
或者,如果您想要任何其他分隔符,例如 ,请使用 (应用 Artem 的答案|
ls | paste -sd'|'
)
在 majkinetor 的答案之上,这是删除尾随分隔符的方法(因为我还不能在他的答案下发表评论):
ls -1 | awk 'ORS=","' | head -c -1
只需删除分隔符所计数的尾随字节即可。
我喜欢这种方法,因为我可以使用多字符分隔符 + 以下其他好处:awk
ls -1 | awk 'ORS=", "' | head -c -2
编辑
正如 Peter 所注意到的,本机 MacOS 版本的 head 不支持负字节计数。但是,这很容易解决。
首先,安装 .“GNU Core Utilities 是 GNU 操作系统的基本文件、外壳和文本操作实用程序。”coreutils
brew install coreutils
MacOS 提供的命令也以前缀“g”安装。例如。gls
完成此操作后,您可以使用具有负字节数的 let,或者更好的是,make alias:ghead
alias head="ghead"
评论
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 的答案,以及其他一些类似的答案,比如这里,是 O(n²),因为每次将新行附加到模式空间时,sed 都必须做 substitute。
为了比较,
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
带有尾部斜杠处理的快速 Perl 版本:
ls -1 | perl -E 'say join ", ", map {chomp; $_} <>'
解释一下:
- perl -E:执行具有功能支持的 Perl(比如说,...)
- 说:打印承运人退货
- join “, ”, ARRAY_HERE:用 “, ” 连接数组
- map {chomp; $_} ROWS:从每一行中删除载体返回并返回结果
- <>:stdin,每行都是一个 ROW,与 map 耦合它将创建每个 ROW 的数组
评论
如果 Python3 是你的菜,你可以这样做(但请解释你为什么要这样做?
ls -1 | python -c "import sys; print(','.join(sys.stdin.read().splitlines()))"
评论
上面的 Python 答案很有趣,但自己的语言甚至可以使输出变得漂亮:
ls -1 |python -c “导入系统;打印(sys.stdin.read().splitlines())”
评论
python -c "import sys; print(' | '.join(sys.stdin.read().splitlines()))"
评论