添加" -I"标记为bash中的路径字符串

时间:2015-06-01 16:08:47

标签: 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/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

3 个答案:

答案 0 :(得分:1)

如果您有阵列中的路径:

paths=(/aaaa/bbbb/ccc /ddas/sdsa/dasd ./dasd/dsd dasd/dsda/dsd dsd/dsad/erer/rerer ../dasd/dsad ../../sdasd/sdsd)

然后你可以使用bash的find-and-replace语法:

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=$1; shift
  # But you need to check $# to make sure the arguments exist :)
  local includes=("{@/#/-I}")
  compile $the_file "${includes[@]}"
}

答案 1 :(得分:1)

您可以使用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[@]}"

答案 2 :(得分:0)

#!/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“哦,上帝不,他正在使用测试!这可能会意外地造成一个无限循环!我们都要死了!”

无限循环不是世界末日。它最糟糕的是一个段错误。偶尔他们甚至可以有用。 OP,您需要确保在测试块中的每个命令末尾包含“&& \”(不带引号);当然除了最后一个。

我学会了这样做,因为我花了一些时间在 Sparta OpenBSD,其中rm和大多数其他工具没有-v标志,我们也不怕无限循环。 ;)