加上「-我";bash中路径字符串的标志

加上「-我";bash中路径字符串的标志,bash,shell,scripting,Bash,Shell,Scripting,具有一串空格分隔的路径,相对或绝对路径,例如: /aaaa/bbbb/ccc /ddas/sdsa/dasd ./dasd/dsd dasd/dsda/dsd dsd/dsad/erer/rerer ../dasd/dsad ../../sdasd/sdsd 我如何在bash中处理这一点,以便用-I预先结束这些路径中的每一条?示例输出应为: -I/aaaa/bbbb/ccc -I/ddas/sdsa/dasd -I./dasd/dsd dasd/dsda/dsd dsd/dsad/erer/r

具有一串空格分隔的路径,相对或绝对路径,例如:

/aaaa/bbbb/ccc /ddas/sdsa/dasd ./dasd/dsd dasd/dsda/dsd dsd/dsad/erer/rerer ../dasd/dsad ../../sdasd/sdsd
我如何在bash中处理这一点,以便用-I预先结束这些路径中的每一条?示例输出应为:

-I/aaaa/bbbb/ccc -I/ddas/sdsa/dasd -I./dasd/dsd dasd/dsda/dsd dsd/dsad/erer/rerer -I../dasd/dsad -I../../sdasd/sdsd
谢谢

编辑上下文: 正如一些人可能已经猜到的那样,这是为了在gcc命令的文件夹路径前面加上-I标志。 我在makefile中使用这个。以下内容(根据anubhava的建议稍作修改)非常有效:

#to include subdirectories in source
TEMP := $(shell find $(SOURCE_PATH)* -type d)
TEMP := $(shell echo $(TEMP) | awk 1 ORS=' ')
TEMP := $(shell printf -- "-I%s " ${TEMP} )
ifdef TEMP
INC_PATHS += $(TEMP)
endif

如果阵列中有路径:

paths=(/aaaa/bbbb/ccc /ddas/sdsa/dasd ./dasd/dsd dasd/dsda/dsd dsd/dsad/erer/rerer ../dasd/dsad ../../sdasd/sdsd)
arr=(/aaaa/bbbb/ccc /ddas/sdsa/dasd ./dasd/dsd dasd/dsda/dsd dsd/dsad/erer/rerer ../dasd/dsad ../../sdasd/sdsd)
printf -v output -- "-I%s " "${arr[@]}"
然后可以使用bash的查找和替换语法:

includes=("${paths[@]/#/-I}")
可以将数组作为一系列参数提供给命令(或函数):

您可以在bash函数中对
$@
(引号中)执行类似的转换

with_includes() {
  # If you need to do something with the first few arguments,
  # collect them here and then call shift:
  #    the_file=$1; shift
  # But you need to check $# to make sure the arguments exist :)
  local includes=("{@/#/-I}")
  compile $the_file "${includes[@]}"
}

您可以使用
printf

s='/aaaa/bbbb/ccc /ddas/sdsa/dasd ./dasd/dsd dasd/dsda/dsd dsd/dsad/erer/rerer ../dasd/dsad ../../sdasd/sdsd'

printf -v output -- "-I%s " $s
echo "$output"
-I/aaaa/bbbb/ccc -I/ddas/sdsa/dasd -I./dasd/dsd -Idasd/dsda/dsd -Idsd/dsad/erer/rerer -I../dasd/dsad -I../../sdasd/sdsd
或者,如果使用数组:

paths=(/aaaa/bbbb/ccc /ddas/sdsa/dasd ./dasd/dsd dasd/dsda/dsd dsd/dsad/erer/rerer ../dasd/dsad ../../sdasd/sdsd)
arr=(/aaaa/bbbb/ccc /ddas/sdsa/dasd ./dasd/dsd dasd/dsda/dsd dsd/dsad/erer/rerer ../dasd/dsad ../../sdasd/sdsd)
printf -v output -- "-I%s " "${arr[@]}"
然而,我同意其他人的观点,这是一种糟糕的形式。理想情况下,您的路径应该位于单独的线上

#!/usr/local/bin/bash

echo "/aaaa/bbbb/ccc /ddas/sdsa/dasd ./dasd/dsd dasd/dsda/dsd \
dsd/dsad/erer/rerer ../dasd/dsad ../../sdasd/sdsd" | \
tr ' ' '\n' > tempfile

let "lines=$(wc -l tempfile | cut -d' ' -f1)"
let "lines=lines+1"
let "counter=1"

function loop() {
[ "${counter}" -lt "${lines}" ] && \
echo "Current loop iteration: ${counter}." && \
sed -n "${counter}p" tempfile | sed s'@^@ -I@'g >> tempfile2 && \
let "counter=counter+1" && \
loop
}

loop

[ -f ./tempfile ] && \
echo "File exists: ./tempfile." && \
rm ./tempfile

[ ! -f ./tempfile ] && \
echo "File deleted: ./tempfile."
然后,您可以编辑tempfile2中每行的开头来执行任何操作,并将其作为shell脚本运行

Inb4“哦,天哪,他在使用测试!这可能会意外地创建一个无限循环!我们都会死!”

无限循环不是世界末日。最糟糕的是它会导致一个SEG故障。有时,它们甚至可能是有用的。不过,您需要确保在测试块中的每个命令末尾都包含“&&\”(不带引号);当然除了最后一个


我学会了这样做,因为我在SpartaOpenBSD中度过了一段时间,rm和大多数其他实用程序都没有-v标志,我们也不怕无限循环

一般来说,假设所有路径本身都不包含空格是不安全的。你是对的。但这只是意味着我需要找到一种方法,首先将这些路径放在引号之间。应该没那么难吧