我想遍历一个我从echo $VARIABLE
命令获得的路径列表。
例如:
echo $MANPATH
将返回
/usr/lib:/usr/sfw/lib:/usr/info
这是三条不同的路径,每条路径用冒号分隔。我想循环每个路径。有没有办法做到这一点?感谢。
感谢到目前为止的所有回复,看起来我实际上根本不需要循环。我只需要一种取出冒号的方法,这样我就可以在这三条路径上运行一个ls
命令。
答案 0 :(得分:47)
您可以设置内部字段分隔符:
( IFS=:
for p in $MANPATH; do
echo "$p"
done
)
我使用了子shell,因此IFS中的更改不会反映在我当前的shell中。
答案 1 :(得分:16)
您可以使用Bash的模式替换parameter expansion来填充循环变量。例如:
MANPATH=/usr/lib:/usr/sfw/lib:/usr/info
# Replace colons with spaces to create list.
for path in ${MANPATH//:/ }; do
echo "$path"
done
注意:请勿将替换扩展括在引号中。您希望MANPATH中的扩展值被for循环解释为单独的单词,而不是单个字符串。
答案 2 :(得分:12)
在Bash中执行此操作的规范方法是适当地使用ReviewController editReview
内置函数:
read
这是唯一可行的解决方案:将完全按照您的意愿执行操作:在分隔符IFS=: read -r -d '' -a path_array < <(printf '%s:\0' "$MANPATH")
上拆分字符串,并且对于空格,换行符和全局字符(如:
,{{)是安全的1}}等等(与其他答案不一样:它们都被打破了。)
执行此命令后,您将拥有一个数组*
,您可以在其上循环:
[ ]
答案 3 :(得分:4)
通过这种方式,您可以通过一个循环安全地浏览$PATH
,而$IFS
将在循环内部或外部保持相同。
while IFS=: read -d: -r path; do # `$IFS` is only set for the `read` command
echo $path
done <<< "${PATH:+"${PATH}:"}" # append an extra ':' if `$PATH` is set
您可以查看$IFS
,
IFS='xxxxxxxx'
while IFS=: read -d: -r path; do
echo "${IFS}${path}"
done <<< "${PATH:+"${PATH}:"}"
,输出将是这样的。
xxxxxxxx/usr/local/bin
xxxxxxxx/usr/bin
xxxxxxxx/bin
答案 4 :(得分:1)
这也可以通过Python在命令行上解决:
python -c "import os,sys;[os.system(' '.join(sys.argv[1:]).format(p)) for p in os.getenv('PATH').split(':')]" echo {}
或者作为别名:
alias foreachpath="python -c \"import os,sys;[os.system(' '.join(sys.argv[1:]).format(p)) for p in os.getenv('PATH').split(':')]\""
使用示例:
foreachpath echo {}
这种方法的优点是{}
将被每个路径连续替换。这可用于构造各种命令,例如列出$PATH
目录中所有文件和目录的大小。包括名称中包含空格的目录:
foreachpath 'for e in "{}"/*; do du -h "$e"; done'
这是一个通过为$PATH
$PATH
中的每个文件和目录创建符号链接来缩短$HOME/.allbin
变量长度的示例。这对于日常使用没有用,但如果在too many arguments
容器中收到docker
错误消息,则可能非常有用,因为bitbake
使用了完整的$PATH
mkdir -p "$HOME/.allbin"
python -c "import os,sys;[os.system(' '.join(sys.argv[1:]).format(p)) for p in os.getenv('PATH').split(':')]" 'for e in "{}"/*; do ln -sf "$e" "$HOME/.allbin/$(basename $e)"; done'
export PATH="$HOME/.allbin"
1}}作为命令行的一部分...
$PATH
理论上,这也应该加速常规shell使用和shell脚本,因为搜索每个执行命令的路径较少。但 非常hacky,所以我不建议任何人以这种方式缩短foreachpath
。
export class LocationComponent {
lat;
lon;
constructor() {
}
go(form) {
form.lat=this.lat;
form.lon=this.lon
this.mapService.esri.go(form.lon, form.lat);
this.dialogRef.close();
}
changeLatLon(value:any){
let latlog=value.split(',');
this.lat=latlog[0];
this.lon=latlog.length>1?latlog[1]:0; //if latlon haven't a ",",
// latlong.length=1
}
}
别名可能会派上用场。
答案 5 :(得分:0)
您可以在$ {}表示法中使用Bash代替X来完成此操作:
for p in ${PATH//:/$'\n'} ; do
echo $p;
done
答案 6 :(得分:0)
for p in $(echo $MANPATH | tr ":" " ") ;do
echo $p
done
答案 7 :(得分:0)
IFS=:
arr=(${MANPATH})
for path in "${arr[@]}" ; do # <- quotes required
echo $path
done
...它确实处理空格:o)但如果你有类似的东西,还会添加空元素:
:/usr/bin::/usr/lib:
...然后索引0,2将为空(''),不能说为什么索引4根本没有设置
答案 8 :(得分:0)
结合以下方面的想法
代码:
PATHVAR='foo:bar baz:spam:eggs:' # demo path with space and empty
printf '%s:\0' "$PATHVAR" | while IFS=: read -d: -r p; do
echo $p
done | cat -n
输出:
1 foo
2 bar baz
3 spam
4 eggs
5