Substituir valores no arquivo

3

Eu tenho arquivos:

$cat file1.txt
1234|W
1345|S
8427|D
2132|C
3243|V

e meu arquivo sql é:

$cat select.sql
SELECT *
  FROM CUSTOMERS
 WHERE ID IN (FLAG);

e eu tenho um shell com as próximas instruções

$cat replace.ksh
!#/bin/ksh

S_ids='awk -F"|" '{print "" $1 "" ","}' file1.txt |sed '$s/,$//''

sed -i "s/FLAG/${S_ids}/g" select.sql

Eu solicitei colocar os valores da variável "S_ids" no arquivo select.sql input da palavra FLAG o resultado deve:

$cat select.sql
SELECT *
  FROM CUSTOMERS
 WHERE ID IN ('1234',
'1345',
'8427',
'2132',
'3243');

Eu tentei sed -i "s/FLAG/${S_ids}/g" select.sql , mas não obtive o resultado esperado.

    
por Miguel Angel 29.04.2016 / 17:06

3 respostas

2

A razão pela qual isso não funciona pode ser inferida a partir da mensagem de erro (que você omitiu fornecer):

sed: -e expression #1, char 14: unterminated 's' command

O comando sed não aceita um valor de várias linhas. Você tem que recolher suas múltiplas linhas em uma única linha. Você poderia fazer isso com um script como este:

#!/bin/ksh
S_ids="'$(cut -d'|' -f1 file1.txt | tr '\n' ' ' | sed -e 's/ *$//' -e "s/ /','/g")'"
sed -i "s/FLAG/${S_ids}/g" select.sql

Para ver como S_ids é gerado, você pode pegar cada parte do pipeline

cut -d'|' -f1 file.txt        # Extract first column
tr '\n' ' '                   # Convert newlines to spaces
sed -e 's/ *$//'              # Strip the trailing space
sed -e "s/ /','/g"            # Replace each remaining space with the three characters ','
    
por 29.04.2016 / 17:59
0
#! /bin/ksh

inputfile='file1.txt'
sqlfile='select.sql'

S_ids=$(awk -F"|" '{gsub(/^|$/,"\'\''",$1) ; print $1","}' "$inputfile" | 
        xargs | 
        sed -e 's/,$//')

sed -i "s/FLAG/${S_ids}/g" "$sqlfile"

Saída:

$ cat select.sql 
SELECT *
  FROM CUSTOMERS
 WHERE ID IN ('1234', '1345', '8427', '2132', '3243');

Isso usa a função awk gsub() para adicionar \' no início e \', no final do primeiro campo de cada linha. Ele adiciona \' , em vez de apenas ' , para que a aspa simples sobreviva ao pipe através de xargs .

Observe o uso de '\'' para incorporar uma aspa simples dentro do script com aspas simples de awk - leia como "aspas finais, aspas simples com escape, aspas simples com início novamente" .

xargs sem nenhum comando para executar os padrões para xargs echo , de modo que todas as linhas de saída sejam colocadas em uma única linha (separadas por primeiros campos de file1.txt), separadas por espaços. Isso funcionará a menos que existam muitas dezenas de milhares de linhas em file1.txt - o suficiente para exceder o comprimento máximo da linha de shell (normalmente 128KB ou mais).

Finalmente, canaliza a saída de xargs para sed para remover o , final da linha.

Se você preferir ter novas linhas após cada ID em select.sql , altere a última linha do script para:

sed -i "s/FLAG/${S_ids}/g; s/, /\n/g" "$sqlfile"

A saída será:

SELECT *
  FROM CUSTOMERS
 WHERE ID IN ('1234',
'1345',
'8427',
'2132',
'3243');
    
por 30.04.2016 / 02:00
0
$ FLAG=$(awk -F\| '{printf("%s, ", $1)}' file1.txt)
$ echo $FLAG 
1234, 1345, 8427, 2132, 3243,
$ sed "s/FLAG/${FLAG%%, }/" select.sql
SELECT *
  FROM CUSTOMERS
 WHERE ID IN (1234, 1345, 8427, 2132, 3243);

Isso depende da lista de sinalizadores ser pequena o suficiente para caber na linha de comando. Se não estiver, você pode usar o getline no awk para processar o arquivo1.txt, coletando a seqüência de caracteres de substituição em um padrão BEGIN e processando o select.sql.

    
por 01.05.2016 / 00:24