Tuyau d'entrée dans un script
J'ai écrit un script shell en ksh pour convertir un fichier CSV dans un Tableur fichier XML. Il prend un fichier CSV existant (le chemin d'accès qui est une variable dans le script), puis crée un nouveau fichier de sortie .xls. Le script n'a pas de paramètres positionnels. Le nom du fichier CSV est actuellement codé en dur dans le script.
Je voudrais modifier le script afin qu'il peut prendre en entrée des données au format CSV à partir d'un tuyau, et donc que l' .xls données de sortie peuvent également être transmis ou redirigé (>) dans un fichier sur la ligne de commande.
Comment cela est-il obtenu?
J'ai du mal à trouver de la documentation sur comment écrire un script shell de prendre une entrée à partir d'un tuyau. Il semble que la "lecture" est utilisé uniquement pour les mst entrée de la kb.
Grâce.
Edit : le script ci-dessous pour plus d'infos (modifié à partir d'un tuyau via le chat, que par la réponse à la question.
#!/bin/ksh
#Script to convert a .csv data to "Spreadsheet ML" XML format - the XML scheme for Excel 2003
#
# Take CSV data as standard input
# Out XLS data as standard output
#
DATE=`date +%Y%m%d`
#define tmp files
INPUT=tmp.csv
IN_FILE=in_file.csv
#take standard input and save as $INPUT (tmp.csv)
cat > $INPUT
#clean input data and save as $IN_FILE (in_file.csv)
grep '.' $INPUT | sed 's/*,/,/g' | sed 's/, */,/g' > $IN_FILE
#delete original $INPUT file (tmp.csv)
rm $INPUT
#detect the number of columns and rows in the input file
ROWS=`wc -l < $IN_FILE | sed 's///g' `
COLS=`awk -F',' '{print NF; exit}' $IN_FILE`
#echo "Total columns is $COLS"
#echo "Total rows is $ROWS"
#create start of Excel File
echo "<?xml version=\"1.0\"?>
<?mso-application progid=\"Excel.Sheet\"?>
<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"
xmlns:o=\"urn:schemas-microsoft-com:office:office\"
xmlns:x=\"urn:schemas-microsoft-com:office:excel\"
xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"
xmlns:html=\"http://www.w3.org/TR/REC-html40\">
<DocumentProperties xmlns=\"urn:schemas-microsoft-com:office:office\">
<Author>Ben Hamilton</Author>
<LastAuthor>Ben Hamilton</LastAuthor>
<Created>${DATE}</Created>
<Company>MCC</Company>
<Version>10.2625</Version>
</DocumentProperties>
<ExcelWorkbook xmlns=\"urn:schemas-microsoft-com:office:excel\">
<WindowHeight>6135</WindowHeight>
<WindowWidth>8445</WindowWidth>
<WindowTopX>240</WindowTopX>
<WindowTopY>120</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID=\"Default\" ss:Name=\"Normal\">
<Alignment ss:Vertical=\"Bottom\" />
<Borders />
<Font />
<Interior />
<NumberFormat />
<Protection />
</Style>
<Style ss:ID=\"AcadDate\">
<NumberFormat ss:Format=\"Short Date\"/>
</Style>
</Styles>
<Worksheet ss:Name=\"Sheet 1\">
<Table>
<Column ss:AutoFitWidth=\"1\" />"
#for each row in turn, create the XML elements for row/column
r=1
while (( r <= $ROWS ))
do
echo "<Row>\n"
c=1
while (( c <= $COLS ))
do
DATA=`sed -n "${r}p" $IN_FILE | cut -d "," -f $c `
if [[ "${DATA}" == [0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][0-9][0-9] ]]; then
DD=`echo $DATA | cut -d "." -f 1`
MM=`echo $DATA | cut -d "." -f 2`
YYYY=`echo $DATA | cut -d "." -f 3`
echo "<Cell ss:StyleID=\"AcadDate\"><Data ss:Type=\"DateTime\">${YYYY}-${MM}-${DD}T00:00:00.000</Data></Cell>"
else
echo "<Cell><Data ss:Type=\"String\">${DATA}</Data></Cell>"
fi
(( c+=1 ))
done
echo "</Row>"
(( r+=1 ))
done
echo "</Table>\n</Worksheet>\n</Workbook>"
rm $IN_FILE > /dev/null
exit 0
OriginalL'auteur Ben Hamilton | 2013-10-16
Vous devez vous connecter pour publier un commentaire.
Commandes à hériter de leur entrée standard du processus qui commence. Dans votre cas, votre script fournit son entrée standard pour chaque commande qu'il exécute. Un simple exemple de script:
Tuyauterie de données dans votre script shell causes
cat
de lire ces données, depuiscat
hérite de son entrée standard à partir de votre script.La
read
de commande est fourni par le shell pour la lecture de texte à partir de l'entrée standard dans une variable du shell si vous n'avez pas d'autre commande pour lire ou de traitement de votre script de l'entrée standard.OriginalL'auteur chepner
Il y a un problème ici. Si vous exécutez le script sans vérifier d'abord pour s'assurer qu'il est d'entrée sur l'entrée standard stdin, puis il va s'accrocher jusqu'à quelque chose qui est tapé.
Donc, pour contourner ce problème, vous pouvez vérifier pour s'assurer qu'il est stdin premier, et si non, alors l'utilisation d'un argument de ligne de commande au lieu donnés.
Créer un script appelé "testPipe.sh"
À tester:
Nous allons ajouter quelques trucs pour un test.txt fichier et de rediriger la sortie de notre script.
De sortie:
Data was piped to this script!
Line: stuff
Line: more stuff
Maintenant, nous allons tester si pas de fournir toutes les entrées:
De sortie:
No input was found on stdin, skipping!
No input given!
Maintenant, nous allons tester si la transmission d'un nom de fichier valide:
De sortie:
No input was found on stdin, skipping!
Filename specified: test.txt
Doing things now..
Et enfin, nous allons tester à l'aide d'un nom de fichier non valide:
De sortie:
No input was found on stdin, skipping!
No input given!
Explication:
Des programmes comme la lecture et le chat va utiliser le stdin si elle est disponible à l'intérieur de la coquille, sinon ils vont attendre d'entrée.
De crédit va à Mike de cette page, dans sa réponse montrant comment vérifier pour l'entrée standard d'entrée: https://unix.stackexchange.com/questions/33049/check-if-pipe-is-empty-and-run-a-command-on-the-data-if-it-isnt?newreg=fb5b291531dd4100837b12bc1836456f
OriginalL'auteur Philip Reese
Si le programme externe (que de la création de scripts) déjà prend en entrée à partir de stdin, votre script n'a pas besoin de faire quoi que ce soit. Par exemple, awk lit l'entrée standard stdin, donc un petit script pour compter le nombre de mots par ligne:
Puis
sorties
OriginalL'auteur glenn jackman