将“-I”标志添加到 bash 中的路径字符串

Add "-I" flag to string of paths in bash

有一串 space 分隔路径,相对或绝对,示例:

/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)

那么您可以使用 bash 的查找和替换语法:

includes=("${paths[@]/#/-I}")

您可以提供数组作为命令(或函数)的一系列参数:

compile $the_file "${includes[@]}"

您可以在 bash 函数

中对 $@(在引号中)进行类似的转换
with_includes() {
  # If you need to do something with the first few arguments,
  # collect them here and then call shift:
  #    the_file=; 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

或者如果使用数组:

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" | \
sed s'/ / -I/'g

不过,我同意其他人的看法,这是一种糟糕的形式。理想情况下,您的路径应该在单独的一行上。

#!/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"Oh God no, he's using test! That could accidentally create an infinite loop! WE'RE ALL GOING TO DIE!"

无限循环并不是世界末日。它会导致的最坏情况是段错误。有时它们甚至很有用。 OP,您需要确保在测试块中的每个命令末尾都包含“&& \”(不带引号);当然最后一个除外

我学会了这样做是因为我在 Sparta OpenBSD 上花了很多时间,其中 rm 和大多数其他实用程序没有 -v 标志,我们也没有不怕无限循环。 ;)