Bash中如何在for循环拼接字符串时添加空格并提取目录前缀
问题与解决方法
问题场景
现有如下字符串:
files="applications/dbt/Dockerfile applications/dbt/cloudbuild.yaml applications/dataform/Dockerfile applications/dataform/cloudbuild.yaml"
需要提取每个路径的前两级目录,拼接成空格分隔的目标字符串:
applications/dbt applications/dbt applications/dataform applications/dataform
但运行现有代码后,输出的字符串没有空格,所有内容连在一起:
applications/dbtapplications/dbtapplications/dataformapplications/dataform
尝试的代码如下:
files="applications/dbt/Dockerfile applications/dbt/cloudbuild.yaml applications/dataform/Dockerfile applications/dataform/cloudbuild.yaml" arr=($files) #extracting the first two directories and saving it to a new string for i in ${arr[@]}; do files2+=$(echo "$i" | cut -d/ -f 1-2); done echo $files2
解决方法
方法1:修改循环逻辑,添加空格并清理末尾冗余
在循环拼接时,每次给截取的路径加上空格,最后移除末尾多余的空格即可:
files="applications/dbt/Dockerfile applications/dbt/cloudbuild.yaml applications/dataform/Dockerfile applications/dataform/cloudbuild.yaml" arr=($files) files2="" for i in "${arr[@]}"; do # 截取前两级目录后追加空格 files2+="$(echo "$i" | cut -d/ -f 1-2) " done # 用bash内置参数替换移除末尾空格(比sed更高效) files2="${files2% }" echo "$files2"
方法2:用xargs简化流程(无需循环)
借助xargs和cut一次性完成分割、截取、拼接,代码更简洁:
files="applications/dbt/Dockerfile applications/dbt/cloudbuild.yaml applications/dataform/Dockerfile applications/dataform/cloudbuild.yaml" files2=$(echo "$files" | xargs -n1 | cut -d/ -f1-2 | xargs) echo "$files2"
xargs -n1:将原字符串按空格拆分为每行一个路径cut -d/ -f1-2:提取每个路径的前两级目录- 最后一个
xargs:将每行内容重新拼接为空格分隔的字符串
方法3:纯bash内置操作(无需外部命令)
利用bash的参数替换功能,不用调用cut也能完成截取:
files="applications/dbt/Dockerfile applications/dbt/cloudbuild.yaml applications/dataform/Dockerfile applications/dataform/cloudbuild.yaml" arr=($files) files2="" for i in "${arr[@]}"; do # 从第三个/开始截断,保留前两级目录 part="${i%%/*/*/*}" files2+="$part " done files2="${files2% }" echo "$files2"
${i%%/*/*/*}是bash的参数扩展语法:匹配从右往左最长的/*/*/*模式并删除,剩下的就是applications/dbt这类前两级目录。
内容的提问来源于stack exchange,提问作者Tanay Maheshwari
相关产品推荐
相关产品推荐

