Script Full Backup

d
Autor: GhosTi
Visto en Blog of Sysadmins
#!/bin/bash
 
 
 
TAR=$(which tar)
TEE=$(which tee)
 
ARGS=2
 
if [ $# -ne $ARGS ]
then
echo “Usage: “$0” file dir”
echo ” file: backup file name”
echo ” dir: path to backup”
exit
fi
 
APP=$0 #app name
FILE=$1“_full.tgz” #backup file
FILE_OLD=$FILE“~” #file backuped before remove
DIR=$2 #path
 
LOG_DIR=/var/log
LOG_FILE=$LOG_DIR“/”${APP##*\/}“.log” #remuevo de APP lo que este antes de la ultima /
 
TODAY=`date “+%Y-%m-%d %a”`
echo $TODAY” *** Backup full *** “ | $TEE -a $LOG_FILE
 
if [ ! -d $DIR ]
then
echo “ERROR: path “$DIR” not exist” | $TEE -a $LOG_FILE
exit
fi
 
#Realizo backup del backup
echo “Rotating files…” | $TEE -a $LOG_FILE
 
if [ -f $FILE ];
then
#cp -v $FILE $FILE_OLD | $TEE -a $LOG_FILE
rm -v $FILE | $TEE -a $LOG_FILE
fi
 
echo “Making backup…” | $TEE -a $LOG_FILE
#Realizo el backup
$TAR -chzf $FILE $DIR | $TEE -a $LOG_FILE
 
if [ $? == 0 ]
then
echo “Backup successfull!”
else
echo “ERROR: error making backup :-( “
fi
Leer más...

Script Backup Incremental.

d
Autor: GhosTi
Visto en Blog of Sysadmins
#!/bin/sh
TAR=$(which tar)
TEE=$(which tee)
 
 
 
ARGS=2
 
if [ $# -ne $ARGS ]
 
then
echo “Usage: “$0” file dir”
echo ” file: backup file name”
echo ” dir: path to backup”
exit
fi
 
APP=$0 #app name
FILE=$1“_incremental.tgz” #backup file
FILE_FULL=$1“_full.tgz” #backup full
FILE_OLD=$FILE“~” #file backuped before remove
DIR=$2 #path
 
LOG_DIR=/var/log
LOG_FILE=$LOG_DIR“/”${APP##*\/}“.log” #remuevo de APP lo que este antes de la ultima /
 
TODAY=`date “+%Y-%m-%d %a”`
echo $TODAY” *** Backup incremental ***” | $TEE -a $LOG_FILE
 
if [ ! -d $DIR ]
then
echo “ERROR: path “$DIR” not exist” | $TEE -a $LOG_FILE
exit
fi
 
# Reviso si existe el backup full
if [ ! -f $FILE_FULL ];
then
echo “ERROR: full backup “$FILE_FULL” not exist!” | $TEE -a $LOG_FILE
exit
fi
 
#Realizo backup del backup
 
echo “Rotating files…” | $TEE $LOG_FILE
 
if [ -f $FILE ];
 
then
#cp -v $FILE $FILE_OLD | $TEE $LOG_FILE
rm -v $FILE | $TEE $LOG_FILE
fi
 
#Realizo el backup
DATE_FULL=“`date \”+%Y-%m-%d %H:%M\” -r “$FILE_FULL“`”
echo “Full backupe created: “$DATE_FULL | $TEE $LOG_FILE
 
echo “Making backup…” | $TEE $LOG_FILE
$TAR -chzf $FILE –newer-mtime=“$DATE_FULL” $DIR | $TEE -a $LOG_FILE
 
if [ $? == 0 ]
then
echo “Backup successfull!”
else
echo “ERROR: error making backup :-( “
fi
Leer más...

DB Version Updater

d
Nombre: DB Version Updater
Autor: Eduardo Cuomo [ eduardo.cuomo.ar@gmail.com ]
Descripción: Script to keep the version of the database model updated, using a simple Linux script.
Más información del Script en reduardo7
#!/bin/bash

# Execute Queries for update.
#
# SQL Query File name format: [version number (BIGINT)][ |-|.|_|,|#|\|][Query description][.sql]
#
# For more help, execute this file into a Terminal without parameters.
#
# Eduardo Cuomo | eduardo.cuomo.ar@gmail.com


# Test if running with "bash" interpreter
if [ "$BASH" = "" ] ; then
    # Run with "bash"
    bash "$0" $@
    exit $?
fi

# DB config
DB_USER="USER"
DB_PASS="PASS"
DB_NAME="DB_NAME"
DB_HOST="localhost"
DB_TABLE="DB_VERSION"
DB_CHARSET="latin1"
DB_PORT="3306"


# DB status
DB_STATUS_EXECUTING="EXECUTING"
DB_STATUS_EXECUTED="EXECUTED"
DB_STATUS_ERROR="ERROR"

# Arguments
ARG_UPDATE="update"
ARG_CREATE="create"
ARG_MARK_UPDATED="mark-updated"

# File format
CHAR_SEP="\ \-\_\,\|\#"
CHAR_SEP_P="\ \-\_\,\|\#\."
FILE_NAME_FORMAT="[version number (BIGINT)][${CHAR_SEP_P}][Query description][.sql]"

# Vars
CURRENT_DIR="$(printf '%q' "$(pwd)")"
DIR_NAME="$(dirname "$(printf '%q' "$(readlink -f "$(printf '%q' "$0")")")")"
result=""
br="
"

# Exit
function ex() {
 echo
 echo "cd $CURRENT_DIR"
 cd $CURRENT_DIR
 echo
 exit $1
}

# Escape String
function escape_string() {
 result=$(printf '%q' "$1")
}

# echo
function e() {
 echo "| $1"
}

# echo line
function e_l() {
 let fillsize=80
 fill="+"
 while [ "$fillsize" -gt "0" ] ; do
  fill="${fill}-" # fill with underscores to work on
  let fillsize=${fillsize}-1
 done
 echo $fill
}

# echo exit
function e_e() {
 e "$1"
 e_l
 ex 1
}

# Show help
function show_help() {
 escape_string "$0"
 script="$result"
 e "Help (this):"
 e " # bash $script"
 e " # bash $script --help"
 e
 e
 e "To use rollback on error, tables must be transactional (InnoDB)."
 e "Use next query to set as InnoDB tables:"
 e "    ALTER TABLE \`TABLE_NAME\` ENGINE = INNODB;"
 e
 e
 e "The SQL files names must have the next format:"
 e " ${FILE_NAME_FORMAT}"
 e "File name examples:"
 e " 0001. Query description.sql"
 e " 0002 - Query description 2.sqL"
 e " 3 Query description 3.Sql"
 e " 04, Query description 4.sQl"
 e " 05_Query description 5.SQL"
 e " 20100617-Query description with date as version number.sql"
 e " 201006170105#Query description with date and time as version number.sql"
 e " 00017|Other Query description.sql"
 e " 00017#Other Query description.sql"
 e
 e
 e "Usage: bash $script [OPTIONS] ACTION [EXTRA]"
 e
 e "OPTION:"
 e "-u, --user     Set DB user name to use."
 e "               Using: '$DB_USER'"
 e "-p, --pass     Set DB password to use."
 e "               Using: '$DB_PASS'"
 e "-d, --db       Set DB name to use."
 e "               Using: '$DB_NAME'"
 e "-h, --host     Set DB host to use."
 e "               Using: '$DB_HOST'"
 e "-P, --port     Set DB host port to use."
 e "               Using: '$DB_PORT'"
 e "--help         This help."
 e
 e "ACTION:"
 e "$ARG_UPDATE         Execute update."
 e "               NOTE: Transaction rollback on MySQL error."
 e "$ARG_CREATE         Create a SQL file to mark all files as executed."
 e "               Uses:"
 e "                 # bash $script $ARG_CREATE [OUT FILE NAME]"
 e "                 # bash $script $ARG_CREATE \"out_file_name.sql\""
 e "                 # bash $script $ARG_CREATE \"0. Mark executed to version X.sql\""
 e "               TIP: You can use version '0' to execute before others already executed files."
 e "$ARG_MARK_UPDATED   Mark all files as executed without execute files."
 e_e
}

# Begin
echo
echo "cd $DIR_NAME"
echo
e ":: DB Updater ::"
cd $DIR_NAME
e_l

# No parameters
if [ $# -eq 0 ] ; then
 show_help
fi

# Options
TMP=`getopt --name="$0" -a --longoptions=user:,pass:,db:,host:,port:,help -o u:,p:,d:,h:,P -- $@`
if [ $? -ne 0 ] ; then
 # Invalid option
 e
 e "Error! Invalid parameters!"
 e
 show_help
fi
eval set -- $TMP

until [ $1 == -- ]; do
 case $1 in
  -u|--user)
   DB_USER=$2
   ;;
  -p|--pass)
   DB_PASS=$2
   ;;
  -d|--db)
   DB_NAME=$2
   ;;
  -h|--host)
   DB_HOST=$2
   ;;
  -P|--port)
   DB_PORT=$2
   ;;
  --help)
   show_help
   ;;
 esac
 shift # move the arg list to the next option or '--'
done
shift # remove the '--', now $1 positioned at first argument if any

# Query: Execute query
function q_e() {
 query=$1
 mysql -h ${DB_HOST} -u ${DB_USER} -p${DB_PASS} -P ${DB_PORT} ${DB_NAME} -e "${query}"
 return $?
}

# Read version from file name
function read_version() {
 result=$(echo "$1" | sed "s/[${CHAR_SEP_P}].*$//" | sed "s/^0*//g")
 if [[ "$result" = "" ]] ; then
  result=0
 fi
 # Check integer
 if [[ $result =~ ^[^0-9]+$ ]] ; then
  e "File name format:"
  e " ${FILE_NAME_FORMAT}"
  e_e "The file '$1' not contains a Version number as start name."
 fi
}

# Read description from file name
function read_description() {
 result=$(echo "$1" | sed "s/[^\d${CHAR_SEP_P}]*//" | sed "s/\.sql.*$//i" | sed "s/^[${CHAR_SEP_P}]*//g")
}

# Create table if not exists
function create_table() {
 q_e "CREATE TABLE IF NOT EXISTS \`${DB_TABLE}\` (\`version\` BIGINT NOT NULL, \`description\` varchar(255) NOT NULL, \`file_name\` varchar(255) NOT NULL, \`executed_date\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, \`status\` VARCHAR(10) NOT NULL DEFAULT '${DB_STATUS_EXECUTING}' COMMENT '${DB_STATUS_EXECUTING}; ${DB_STATUS_EXECUTED}; ${DB_STATUS_ERROR}', PRIMARY KEY (\`version\`)) ENGINE=InnoDB DEFAULT CHARSET=latin1"
    if [ $? -ne 0 ]; then
        e_e "[ERROR CODE 7001] QUERY ERROR! mysql exit code: $?"
    fi
 e "Connected to ${DB_USER}@${DB_HOST}.${DB_NAME}"
 e_l
}

# Read file data
file_name=""
file_nameq=""
version=""
versionq=""
desc=""
descq=""
function read_file_data() {
 file_name="$1"
 # File name
 escape_string "$file_name" ; file_nameq=$result
 e "File:         $file_name"
 # Version
 read_version "$file_name" ; version=$result
 escape_string $version ; versionq=$result
 e "Version:      $version"
 # Description
 read_description "$file_name" ; desc=$result
 escape_string "$desc" ; descq=$result
 e "Description:  $desc"
}

# Update DB
if [ "$1" = "${ARG_UPDATE}" ] ; then
 # Update
 e "Updating DB ${DB_HOST}@${DB_NAME}..."
 e_l

 # Create table if not exists
 create_table

 # Begin
 for file in *.sql ; do
  if [[ "$file" =~ ^[0-9]+[${CHAR_SEP_P}]+.+\.[sS][qQ][lL]$ ]] ; then
   read_file_data "$file"

   # Check
   q_e "DELETE FROM \`${DB_TABLE}\` WHERE \`version\` = ${version} AND \`status\` = '${DB_STATUS_ERROR}'"
   q_e "INSERT INTO \`${DB_TABLE}\` (\`version\`, \`description\`, \`file_name\`, \`status\`) VALUES (${version}, '$descq', '$file_nameq', '${DB_STATUS_EXECUTING}')" &> /dev/null

   if [ $? -ne 0 ]; then
    # Already executed
    e "* Already executed."
   else
    e "* Executing update..."
    # Prepare query
    update_query=$(cat "$file")
    update_query="SET SQL_MODE=\"NO_AUTO_VALUE_ON_ZERO\"; SET AUTOCOMMIT=0; START TRANSACTION;
-- BEGIN UPDATE

$update_query ;

-- END UPDATE
COMMIT;"
    query_executed="UPDATE \`${DB_TABLE}\` SET \`status\` = '${DB_STATUS_EXECUTED}' WHERE \`version\` = ${version}"
    # Execute query file
    #mysql -h ${DB_HOST} -u ${DB_USER} -p${DB_PASS} -P ${DB_PORT} --default-character-set=${DB_CHARSET} ${DB_NAME} < "$file"
    mysql -h ${DB_HOST} -u ${DB_USER} -p${DB_PASS} -P ${DB_PORT} --default-character-set=${DB_CHARSET} ${DB_NAME} <<< "$update_query"
    exc=$?
    if [ $exc -ne 0 ]; then
     e
     q_e "UPDATE \`${DB_TABLE}\` SET \`status\` = '${DB_STATUS_ERROR}' WHERE \`version\` = ${version}"
     e "[ERROR CODE 7003] QUERY ERROR! mysql exit code: $exc"
     e "QUERY:${br}${br}$update_query${br}"
     e
     e "Mark this script as executed:"
     e_e "${query_executed};"
    fi
    # Ok
    q_e "$query_executed"
    e "Query executed!"
   fi
   e_l
  fi
 done

 # Finish!
 e "DB ${DB_HOST}@${DB_NAME} updated!"
 e_l

 echo
 echo
 echo "Finish!"
 ex 0
fi

# Mark all files as executed without execute files
if [ "$1" = "${ARG_MARK_UPDATED}" ] ; then
 # Update
 e "Marking as updated DB ${DB_HOST}@${DB_NAME}..."
 e_l

 # Create table if not exists
 create_table

 # Begin
 for file in *.sql ; do
  if [[ "$file" =~ ^[0-9]+[${CHAR_SEP_P}]+.+\.[sS][qQ][lL]$ ]] ; then
   read_file_data "$file"

   # Check
   q_e "DELETE FROM \`${DB_TABLE}\` WHERE \`version\` = ${version} AND \`status\` = '${DB_STATUS_ERROR}'"
   q_e "INSERT INTO \`${DB_TABLE}\` (\`version\`, \`description\`, \`file_name\`, \`status\`) VALUES (${version}, '$descq', '$file_nameq', '${DB_STATUS_EXECUTING}')" &> /dev/null

   if [ $? -ne 0 ]; then
    # Already executed
    e "* Already executed."
   else
    # Mark as executed
    e "* Marking as updated..."
    query_executed="UPDATE \`${DB_TABLE}\` SET \`status\` = '${DB_STATUS_EXECUTED}' WHERE \`version\` = ${version}"
    q_e "$query_executed"
    e "Query executed!"
   fi
   e_l
  fi
 done

 # Finish!
 e "DB ${DB_HOST}@${DB_NAME} marked as updated!"
 e_l

 echo
 echo
 echo "Finish!"
 ex 0
fi

# Create start status file
if [ "$1" = "${ARG_CREATE}" ] ; then
 if [ $# -eq 2 ] ; then
  file_out="$2"
  e "Creating '$file_out' file..."
  e_l

  # Create out file
  echo "INSERT INTO \`${DB_TABLE}\` (\`version\`, \`description\`, \`file_name\`, \`status\`) VALUES" > "$file_out"
  flag=1

  for file in *.sql ; do
   if [[ "$file" =~ ^[0-9]+[${CHAR_SEP_P}]+.+\.[sS][qQ][lL]$ ]] ; then
    if [ "$file" != "$file_out" ] ; then
     read_file_data "$file"

     query=$(echo "(${versionq}, '${descq}', '${file_nameq}', '${DB_STATUS_EXECUTED}')")

     # Add query
     if [ $flag -ne 1 ] ; then
      query=", $query"
     else
      flag=0
     fi
     echo "$query" >> "$file_out"

     e_l
    fi
   fi
  done

  echo ";" >> "$file_out"

  # End
  e "'$file_out' file created!"
  e_l

  echo
  echo
  echo "Finish!"
  ex 0
 fi
fi

# Invalid ACTION
e "INVALID ACTION!"
e_l
show_help
Leer más...

Script Backup MySQL.

d
Nombre: script_backup_mysql.sh
Autor: Desconocido
Visto y información de configuración en Ciber Terminal
#!/bin/bash
BACKUPUSER="backup_user"
BACKUPPASS="PASSWORD"
BACKUPPATH="/home/backup/mysql"
MYDATE="$(date +%Y%m%d)"
MYSQLDUMP="/usr/bin/mysqldump"
MYSQL="/usr/bin/mysql"
MYCNF="/etc/mysql/my.cnf"
ZIP="/bin/bzip2"
ZIPOPS="-9f"
IGNOREDDBB="Database|mysql|information_schema"
 
DBLIST=""
CHMOD="440"
CHOWN="root:admins"
 
BINLOGINDEX="/home/mysql/log/mysql-bin.index"
 
list_databases()
{
        DBLIST="`echo "show databases ;" | $MYSQL -u "$BACKUPUSER" --password="$BACKUPPASS" | egrep -v "$IGNOREDDBB"`"
         return 1
}
 
dump_databases()
{
        for i in $DBLIST
        do
                $MYSQLDUMP --master-data=2 -u "$BACKUPUSER" --password="$BACKUPPASS" $i > $BACKUPPATH/$i-$MYDATE.sql
                $ZIP $ZIPOPS $BACKUPPATH/$i-$MYDATE.sql
        done
        return 1
}
 
dump_grants()
{
        mysql -p$BACKUPPASS --batch --skip-column-names --execute="SELECT DISTINCT CONCAT('SHOW GRANTS FOR ',user,'@\'',host,'\';') AS query FROM user" mysql | mysql -p$BACKUPPASS --batch --skip-column-names mysql | perl -p -e '$_ =~ s/$/;/; END { print "FLUSH PRIVILEGES;n" }' > $BACKUPPATH/grants-$MYDATE.sql
        $ZIP $ZIPOPS $BACKUPPATH/grants-$MYDATE.sql
}
 
 
binlog_backup()
{
        local let LINES=$(cat $BINLOGINDEX | wc -l)
        let LINES--
        tar cjfv $BACKUPPATH/MYSQL_BINLOGS-$MYDATE.tar.bz2 $(head -$LINES $BINLOGINDEX | xargs)
}
 
 
 
purge_binlogs()
{
        local LOGBIN="$(cat $MYCNF | grep -v ^# | grep log_bin | awk -F= '{print $2}')"
        local BINLOGNAME="$(basename $LOGBIN | awk -F. '{print $1}')"
        local BINLOGPATH="$(dirname $LOGBIN)"
        local let MINAGE="$(cat $MYCNF | grep -v ^# | grep expire | awk -F\= '{print $2}')"
        let MINAGE=$((${MINAGE}+2))
        local LASTBINLOG="$(find $BINLOGPATH -mtime +$MINAGE -name "*$BINLOGNAME*" | tail -1)"
        if [[ "$LASTBINLOG" ]]
        then
                local LASTBINLOG="$(basename $LASTBINLOG)"
                echo "PURGE BINARY LOGS TO "$LASTBINLOG";" | $MYSQL -u "$BACKUPUSER" --password="$BACKUPPASS"
        fi
}
 
list_databases
dump_databases
dump_grants
purge_binlogs
 
find $BACKUPPATH -type f -exec chmod $CHMOD {} ;
find $BACKUPPATH -type f -exec chown $CHOWN {} ;
 
exit 0
Leer más...

Script para realizar backup de base de datos MySql y enviarlo por SSH a otro servidor.

d
Autor: FG
Visto en Crea tu software
!/bin/bash
 
#
# Autor : FG 29.03.2011
# Modif.: FG 30.03.2011
# Script para realizar backup de la base 
# de datos MySql
#
# Crontab:
# m h  dom mon dow   command
#00 04 01 * *    /usr/local/bin/backup.sh
#
 
# Configuracion base de datos
DbUser=root
DbHost=127.0.0.1
DbPass=1234
DbName=pruebas
 
# Configuracion numero maximo de backups a guardar
MaxBackups=7
 
# Configuracion de comandos
MySqlDump_cmd=/usr/bin/mysqldump
Tar_cmd=/bin/tar
LOCAL_SCP_CMD=/usr/bin/scp
LOCAL_SSH_CMD=/usr/bin/ssh
 
# Configuracion de directorios
DirTmp=/tmp
DirBackup=/backups 
 
# Configuracion archivo de backup
HOY=`date +"%Y-%m-%d_%H_%M_%S"`
FileNameBackup=backup_$HOY
 
# Configuracion archivos temporales y backups (Ojo no cambiar la extension del archivo)
FileTmpBackup=$DirTmp/$FileNameBackup.sql
FileBackup=$DirBackup/$FileNameBackup.tgz
BackupsFilePath=$DirTmp/backupspaths
 
# Configuracion SSH para enviar backup a otro servidor
ENABLED_REMOTE_BACKUP_SSH=1
CLAVE_SSH=/usr/local/bin/ssh_keys/id_rsa
IP_REMOTE_SSH=192.168.0.1
PORT_REMOTE_SSH=22
USER_SSH=root
HOY_SSH=`date +"%u"`
FileNameBackup_SSH=backup_$HOY_SSH.tgz
REMOTE_FILE_SSH=/ backups/ $FileNameBackup_SSH
LOCAL_FILE_SSH=$FileBackup
 
# Inicio del proceso de backup
 
echo "Generando backup de la base de Datos MySql..."
 
# Comprobacion de existencia de los directorios necesarios
if [ ! -d "$DirTmp" ]; then
    echo "Error, el directorio temporal '$DirTmp' no existe."    
    exit
fi
 
if [ ! -d "$DirBackup" ]; then
    echo "Error, el directorio para las copias '$DirBackup' no existe."
    exit
fi
 
# Crear archivo SQL con estructura y datos de la base de datos MySql   
$MySqlDump_cmd -u $DbUser --host $DbHost --password=$DbPass $DbName > $FileTmpBackup
chmod 777 $FileTmpBackup
 
# Comprime el script de backup de la base de datos MySql
$Tar_cmd czvf $FileBackup $FileTmpBackup &> /dev/null 
rm $FileTmpBackup 
 
# Borra los backups antiguos
echo "Realizado limpieza de backups antiguos..."
 
find $DirBackup -name '*.tgz' | sort -r > $BackupsFilePath
chmod 777 $BackupsFilePath
 
i=1
 
while read file; do        
    if [ $i -gt $MaxBackups  ]; then
        echo "Eliminando backup antiguo: $file "
        chmod 777 $file
        rm $file
    fi
 
    i=`expr $i + 1`                
done < $BackupsFilePath
 
rm $BackupsFilePath
 
# Envia el backup al servidor remoto si la funcion esta activada
if [ $ENABLED_REMOTE_BACKUP_SSH = 1 ]; then
       echo "Copiando backup al servidor remoto..."




      $LOCAL_SCP_CMD -P $PORT_REMOTE_SSH \ 
      -i $CLAVE_SSH $LOCAL_FILE_SSH \ 
      $USER_SSH@$IP_REMOTE_SSH:$REMOTE_FILE_SSH
fi
 
echo "Terminado de realizar backup de la base de Datos MySql."

Leer más...

Script para comprobar si una IP genera Spam

d
Autor: Martín Gómez
Visto en Imsitega
#!/bin/bash
 
for ip in `cat /ruta/archivo-ips`
do
        url=http://www.stopforumspam.com/api?ip=$ip
        respuesta=`curl -s $url | sed -ne '/<\/appears>/ { s/<[^>]*>\(.*\)<\/appears>/\1/; p }'`
        if [ $respuesta = "yes" ];
        then
                echo $ip " Aparece"
       else
               echo $ip "  No aparece"
        fi
 
done
Leer más...

Find all users in group

d
Nombre: belong.sh
Autor: @Tonejito
Visto en Tonejito
#!/bin/sh
#  = ^ . ^ =
#
# ./belong.sh - Get all users in group
# Andres Hernandez (tonejito)
# http://tonejito.blogspot.com:80/
 
SED=/bin/sed
AWK=/usr/bin/awk
GETENT=/usr/bin/getent
 
GROUP=${1}
 
# Find users whose initial login group is $GROUP
$GETENT passwd | awk -F : "\$4==`$GETENT group $GROUP | awk -F : '{print $3}'` {print \$1}"
 
# Find users whose supplementary group is $GROUP
$GETENT group $GROUP | $AWK -F : '{print $4}' | $SED -e 's/,/\n/g'
Leer más...