使用“ls”并保留结果数组中的空格

问题描述 投票:0回答:3

我试图用“ls”读取目录并对其进行操作

目录示例:

$ ls -1
x x
y y
z z

脚本文件:myScript.sh

#!/bin/bash
files=(`ls -1`); 
for ((i=0; i<"${#files[@]}"; i+=1 )); do
    echo "${files[$i]}"
done

但是,输出是

$ myScript.sh
x
x
y
y
z
z

然而,如果我以下列方式定义“文件”

$ files=("x x" "y y" "z z")
$ for ((i=0; i<"${#files[@]}"; i+=1 )); do echo "${files[$i]}"; done
x x
y y
z z

如何保存“files =(`ls -1`)”中的空格?

arrays bash ls spaces preserve
3个回答
3
投票

Don't.

看到:


If at all possible, use a shell glob instead.

也就是说:

files=( * )

If you need to represent filenames as a stream of text, use NUL delimiters.

也就是说,要么:

printf '%s\0' *

要么

find . -mindepth 1 -maxdepth 1 -print0

将发出一个NUL分隔的字符串,您可以使用(在现代bash 4.x中)安全地加载到shell数组中:

readarray -d '' array < <(find . -mindepth 1 -maxdepth 1 -print0)

...或者,支持bash 3.x:

array=( )
while IFS= read -r -d '' name; do
  array+=( "$name" )
done < <(find . -mindepth 1 -maxdepth 1 -print0)

在上面的任何一个中,find命令可能位于FIFO,网络流或其他远程处理层的另一端(假设存在某种复杂性导致您无法使用本机shell glob)。


1
投票

似乎主要的结论是不使用ls。回到更新世的Unix编程时代,他们使用了ls;然而,如今,ls最受限制只能制作人类可读的显示器。一个强大的脚本可以在你的脚本中抛出任何东西(终点线,空白区域,混合了希伯来语和法语的汉字,或者其他什么),最好通过某种形式的通配(如其他人推荐的BashPitfalls)来实现。

#!/bin/bash
 for file in ./*; do
    [ -e "${file}" ] || continue
    # do some task, for example, test if it is a directory.
    if [ -d "${file}" ]; then
        echo "${file}"
    fi
done

./可能不是绝对必要的,但如果文件以“ - ”开头,澄清哪个文件有返回行(或行),可能还有其他一些讨厌的bug。这也是特定文件(.e.g,./*.pdf)的有用模板。例如,假设您的目录中存在以下文件:“ - t”和“<CR>t”。然后(使用非标准字符时显示ls的其他问题)

$ ls
-t  ?t
$ for file in *; do ls "${file}"; done
-t  ?t
?t

然而:

$ for file in ./*; do ls "${file}"; done
./-t
./?t

$ for file in ./*; do echo "${file}"; done
./-t
./
t

可以通过--实现POSIX命令的解决方法

$ for file in *; do ls -- "${file}"; done # work around
-t
?t

-3
投票

试试这个:

eval files=($(ls -Q))

选项-Q可以引用文件名。如果输出不是tty,则选项-1是隐含的(不需要)。

© www.soinside.com 2019 - 2024. All rights reserved.